|
| 1 | +--- |
| 2 | +category: Integrate |
| 3 | +title: OAuth 2.0 Authorization Code Flow |
| 4 | +--- |
| 5 | +# OAuth 2.0 Authorization Code Flow |
| 6 | + |
| 7 | +Use the Authorization Code flow when your application acts on behalf of a Matomo user. |
| 8 | + |
| 9 | +## Flow overview |
| 10 | + |
| 11 | +The Authorization Code flow works like this: |
| 12 | + |
| 13 | +1. Your application redirects the user to the Matomo authorization endpoint. |
| 14 | +2. The user logs in, reviews the requested permissions, and approves access. |
| 15 | +3. Matomo redirects back with an authorization `code`. |
| 16 | +4. Your application exchanges the code for an access token. |
| 17 | +5. Your application calls Matomo APIs using `Authorization: Bearer ACCESS_TOKEN`. |
| 18 | + |
| 19 | +## PKCE for public clients |
| 20 | + |
| 21 | +Public clients should use PKCE. PKCE requires a `code_verifier` and a derived `code_challenge`. |
| 22 | + |
| 23 | +Example values: |
| 24 | + |
| 25 | +```text |
| 26 | +code_verifier = dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk |
| 27 | +code_challenge = E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM |
| 28 | +``` |
| 29 | + |
| 30 | +Where: |
| 31 | + |
| 32 | +```text |
| 33 | +code_challenge = BASE64URL(SHA256(code_verifier)) |
| 34 | +``` |
| 35 | + |
| 36 | +## Redirect the user to the authorization endpoint |
| 37 | + |
| 38 | +### Public client with PKCE |
| 39 | + |
| 40 | +```text |
| 41 | +https://matomo.example.com/index.php?module=OAuth2&action=authorize |
| 42 | +&response_type=code |
| 43 | +&client_id=analytics_app |
| 44 | +&redirect_uri=https://example-app.com/oauth/callback |
| 45 | +&scope=matomo:read |
| 46 | +&state=abc123 |
| 47 | +&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM |
| 48 | +&code_challenge_method=S256 |
| 49 | +``` |
| 50 | + |
| 51 | +### Confidential client |
| 52 | + |
| 53 | +```text |
| 54 | +https://matomo.example.com/index.php?module=OAuth2&action=authorize |
| 55 | +&response_type=code |
| 56 | +&client_id=analytics_app |
| 57 | +&redirect_uri=https://example-app.com/oauth/callback |
| 58 | +&scope=matomo:read |
| 59 | +&state=abc123 |
| 60 | +``` |
| 61 | + |
| 62 | +The user will: |
| 63 | + |
| 64 | +1. Log in to Matomo. |
| 65 | +2. Review the requested permissions. |
| 66 | +3. Click **Allow**. |
| 67 | + |
| 68 | +After approval, Matomo redirects back to your application: |
| 69 | + |
| 70 | +```text |
| 71 | +https://example-app.com/oauth/callback?code=AUTHORIZATION_CODE&state=abc123 |
| 72 | +``` |
| 73 | + |
| 74 | +## Exchange the authorization code for tokens |
| 75 | + |
| 76 | +The requested scope needs to match the client configuration. At the time of writing, the plugin allows only one scope per request. |
| 77 | + |
| 78 | +### PKCE token request |
| 79 | + |
| 80 | +```bash |
| 81 | +curl -X POST 'https://matomo.example.com/index.php?module=OAuth2&action=token' \ |
| 82 | + -H 'Content-Type: application/x-www-form-urlencoded' \ |
| 83 | + -d 'grant_type=authorization_code' \ |
| 84 | + -d 'client_id=analytics_app' \ |
| 85 | + -d 'redirect_uri=https://example-app.com/oauth/callback' \ |
| 86 | + -d 'code=AUTHORIZATION_CODE' \ |
| 87 | + -d 'code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk' |
| 88 | +``` |
| 89 | + |
| 90 | +### Confidential client token request |
| 91 | + |
| 92 | +```bash |
| 93 | +curl -X POST 'https://matomo.example.com/index.php?module=OAuth2&action=token' \ |
| 94 | + -H 'Content-Type: application/x-www-form-urlencoded' \ |
| 95 | + -d 'grant_type=authorization_code' \ |
| 96 | + -d 'client_id=analytics_app' \ |
| 97 | + -d 'client_secret=7fa9c0f81b8b4a12' \ |
| 98 | + -d 'redirect_uri=https://example-app.com/oauth/callback' \ |
| 99 | + -d 'code=AUTHORIZATION_CODE' |
| 100 | +``` |
| 101 | + |
| 102 | +## Example token response |
| 103 | + |
| 104 | +```json |
| 105 | +{ |
| 106 | + "token_type": "Bearer", |
| 107 | + "expires_in": 3600, |
| 108 | + "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", |
| 109 | + "refresh_token": "def50200a1b9" |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | +## Refresh an access token |
| 114 | + |
| 115 | +Use a refresh token to obtain a new access token. |
| 116 | + |
| 117 | +### Public client |
| 118 | + |
| 119 | +```bash |
| 120 | +curl -X POST 'https://matomo.example.com/index.php?module=OAuth2&action=token' \ |
| 121 | + -H 'Content-Type: application/x-www-form-urlencoded' \ |
| 122 | + -d 'grant_type=refresh_token' \ |
| 123 | + -d 'client_id=analytics_app' \ |
| 124 | + -d 'refresh_token=def50200a1b9' |
| 125 | +``` |
| 126 | + |
| 127 | +### Confidential client |
| 128 | + |
| 129 | +```bash |
| 130 | +curl -X POST 'https://matomo.example.com/index.php?module=OAuth2&action=token' \ |
| 131 | + -H 'Content-Type: application/x-www-form-urlencoded' \ |
| 132 | + -d 'grant_type=refresh_token' \ |
| 133 | + -d 'client_id=analytics_app' \ |
| 134 | + -d 'client_secret=7fa9c0f81b8b4a12' \ |
| 135 | + -d 'refresh_token=def50200a1b9' |
| 136 | +``` |
| 137 | + |
| 138 | +## What to read next |
| 139 | + |
| 140 | +Once you have an access token, see [Calling Matomo APIs with OAuth 2.0](/guides/oauth2/api-usage). |
0 commit comments