doc/api/oauth_endpoints.md
See <a href="http://tools.ietf.org/html/rfc6749#section-4.1.3">Section 4.1.3</a> of the OAuth2 RFC for more information about this process.
<h3 class="endpoint">POST /login/oauth2/token</h3> <h4>Parameters</h4> <table class="request-params"> <thead> <tr> <th class="param-name">Parameter</th> <!-- Intentionally using class="param-desc" to keep the column wide --> <th class="param-desc">Required</th> <th class="param-desc">Description</th> </tr> </thead> <tbody> <tr class="request-param"> <td>grant_type</td> <td>Required</td> <td class="param-desc">Values currently supported: "authorization_code", "refresh_token", and "client_credentials".</td> </tr> <tr class="request-param"> <td>client_id</td> <td>Required for grant_types: authorization_code, refresh_token</td> <td class="param-desc">The client id for your registered application.</td> </tr> <tr class="request-param"> <td>client_secret</td> <td>Required for grant_types: authorization_code, refresh_token</td> <td class="param-desc">The client secret for your registered application.</td> </tr> <tr class="request-param"> <td>redirect_uri</td> <td>Required for grant_types: authorization_code, refresh_token</td> <td class="param-desc">If a redirect_uri was passed to the initial request in step 1, the same redirect_uri must be given here.</td> </tr> <tr class="request-param"> <td>code</td> <td>Required for grant_type: authorization_code</td> <td class="param-desc">Required if grant_type is authorization_code. The code you received in a redirect response.</td> </tr> <tr class="request-param"> <td>refresh_token</td> <td>Required for grant_type: refresh_token</td> <td class="param-desc">Required if grant_type is refresh_token. The refresh_token you received in a redirect response.</td> </tr> <tr class="request-param"> <td>client_assertion_type</td> <td>Required for grant_type: client_credentials</td> <td class="param-desc">Currently the only supported value for this field is `urn:ietf:params:oauth:client-assertion-type:jwt-bearer`.</td> </tr> <tr class="request-param"> <td>client_assertion</td> <td>Required for grant_type: client_credentials</td> <td class="param-desc">The signed jwt used to request an access token. Includes the value of Developer Key id as the sub claim of the jwt body. Should be signed by the private key of the stored public key on the DeveloperKey.</td> </tr> <tr class="request-param"> <td>scope</td> <td>Required for grant_type: client_credentials</td> <td class="param-desc">A list of scopes to be granted to the token. Currently only IMS defined scopes may be used.</td> </tr> </tbody> </table> <h4>Canvas API example responses</h4> <p>For grant_type of code or refresh_token:</p> <table class="request-params"> <thead> <tr> <th class="param-name">Parameter</th> <th class="param-desc">Description</th> </tr> </thead> <tbody> <tr class="request-param"> <td>access_token</td> <td class="param-desc">The OAuth2 Canvas API access token.</td> </tr> <tr class="request-param"> <td>token_type</td> <td class="param-desc">The type of token that is returned.</td> </tr> <tr class="request-param"> <td>user</td> <td class="param-desc">A JSON object of canvas user id and user name.</td> </tr> <tr class="request-param"> <td>refresh_token</td> <td class="param-desc">The OAuth2 refresh token.</td> </tr> <tr class="request-param"> <td>expires_in</td> <td class="param-desc">Seconds until the access token expires.</td> </tr> <tr class="request-param"> <td>canvas_region</td> <td class="param-desc">For hosted Canvas, the AWS region (e.g. us-east-1) in which the institution that provided this token resides. For local or open source Canvas, this will have a value of "unknown". This field is safe to ignore.</td> </tr> </tbody> </table> <p>When using grant_type=code (ex: for Canvas API access):</p> <pre class="example code prettyprint"> { "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "token_type": "Bearer", "user": {"id":42, "name": "Jimi Hendrix"}, "refresh_token": "tIh2YBWGiC0GgGRglT9Ylwv2MnTvy8csfGyfK2PqZmkFYYqYZ0wui4tzI7uBwnN2", "expires_in": 3600, "canvas_region": "us-east-1" } </pre> <p>When using grant_type=refresh_token, the response will not contain a new refresh token since the same refresh token can be used multiple times:</p> <pre class="example code prettyprint"> { "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "token_type": "Bearer", "user": {"id":42, "name": "Jimi Hendrix"}, "expires_in": 3600 } </pre> <p>If scope=/auth/userinfo was specified in the <a href="file.oauth_endpoints.html#get-login-oauth2-auth">GET login/oauth2/auth</a> request (ex: when using Canvas as an authentication service) then the response that results from <a href="file.oauth_endpoints.html#post-login-oauth2-token">POST login/oauth2/token</a> would be:</p> <pre class="example code prettyprint"> { "access_token": null, "token_type": "Bearer", "user":{"id": 42, "name": "Jimi Hendrix"} } </pre> <h4>Examples using client_credentials</h4> <p>When using grant_type=client_credentials (ex: <a href="file.oauth.html#accessing-lti-advantage-services">to access LTI Advantage Services</a>):</p> <h5>Example request</h5> <p>This request must be signed by an RSA256 private key with a public key that is configured on the developer key as described in <a href="file.oauth.html#developer-key-setup" target="_blank">Step 1: Developer Key Setup</a>.</p> <pre class="example code prettyprint"> { "grant_type": "client_credentials", "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", "client_assertion": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjIwMTktMDYtMjFUMTQ6NTk6MzBaIn0.eyJpc3MiOiJodHRwczovL3d3dy5teS10b29sLmNvbSIsInN1YiI6Ilx1MDAzY2NsaWVudF9pZFx1MDAzZSIsImF1ZCI6Imh0dHA6Ly9cdTAwM2NjYW52YXNfZG9tYWluXHUwMDNlL2xvZ2luL29hdXRoMi90b2tlbiIsImlhdCI6MTU2MTc1MDAzMSwiZXhwIjoxNTYxNzUwNjMxLCJqdGkiOiJkZmZkYmRjZS1hOWYxLTQyN2ItOGZjYS02MDQxODIxOTg3ODMifQ.lUHCwDqx2ukKQ2vwoz_824IVcyq-rNdJKVpGUiJea5-Ybk_VfyKW5v0ky-4XTJrGHkDcj0T9J8qKfYbikqyetK44yXx1YGo-2Pn2GEZ26bZxCnuDUDhbqN8OZf4T8DnZsYP4OyhOseHERsHCzKF-SD2_Pk6ES5-Z8J55_aMyS3w3tl4nJtwsMm6FbMDp_FhSGE4xTwkBZ2KNM4JqkCwHGX_9KcpsPsHRFQjn9ysTeg-Qf7H2QFgFMFjsfQX-iSL_bQoC2npSz7rQ8awKMhCEYdMYZk2vVhQ7XQ8ysAyf3m1vlLbHjASpztcAB0lz_DJysT0Ep-Rh311Qf_vXHexjVA", "scope": "https://purl.imsglobal.org/spec/lti-ags/lineitem https://purl.imsglobal.org/spec/lti-ags/result/read" } </pre> <p>Below is an example of the decoded client_assertion JWT in the above request:</p> <pre class="example code prettyprint"> //Header { "typ": "JWT", "alg": "RS256", "kid": "2019-06-21T14:59:30Z" } //Payload { "iss": "https://www.my-tool.com", "sub": "<client_id>", "aud": "https://<canvas_domain>/login/oauth2/token", "iat": 1561750031, "exp": 1561750631, "jti": "dffdbdce-a9f1-427b-8fca-604182198783" } </pre> <p>NOTE:</p> <ul> <li>the value of the sub claim should match the client_id of the developer key in Canvas.</li> <li>the value of the aud claim should contain either the domain of the Canvas account where the desired data resides, or the domain of the LTI 1.3 OIDC Auth endpoint, as described <a href="file.lti_launch_overview.html#step-2" target="_blank">here</a>.</li> <li>if the public key defined on the developer key is a JWK set (specified by an URL) the kid (key ID) value in the signed JWT header must match one of the public keys returned by the public key URL.</li> </ul> <h5>Example Response</h5> <table class="request-params"> <thead> <tr> <th class="param-name">Parameter</th> <th class="param-desc">Description</th> </tr> </thead> <tbody> <tr class="request-param"> <td>access_token</td> <td class="param-desc">The OAuth2 client_credentials access token.</td> </tr> <tr class="request-param"> <td>token_type</td> <td class="param-desc">The type of token that is returned.</td> </tr> <tr class="request-param"> <td>expires_in</td> <td class="param-desc">Seconds until the access token expires.</td> </tr> <tr class="request-param"> <td>scope</td> <td class="param-desc">The scope or space delimited list of scopes granted for the access token.</td> </tr> </tbody> </table> <pre class="example code prettyprint"> { "access_token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3d3cuZXhhbXBsZS5jb20iLCJpYXQiOiIxNDg1OTA3MjAwIiwiZXhwIjoiMTQ4NTkwNzUwMCIsImltc2dsb2JhbC5vcmcuc2VjdXJpdHkuc2NvcGUiOiJMdGlMaW5rU2V0dGluZ3MgU2NvcmUuaXRlbS5QVVQifQ.UWCuoD05KDYVQHEcciTV88YYtWWMwgb3sTbrjwxGBZA", "token_type" : "Bearer", "expires_in" : 3600, "scope" : "https://purl.imsglobal.org/spec/lti-ags/lineitem https://purl.imsglobal.org/spec/lti-ags/result/read" } </pre> </div>If your application supports logout functionality, you can revoke your own access token. This is useful for security reasons, as well as removing your application from the list of tokens on the user's profile page. Simply make an authenticated request to the following endpoint by including an Authorization header or providing the access_token as a request parameter.
<h3 class="endpoint">DELETE /login/oauth2/token</h3> <h4>Parameters</h4> <table class="request-params"> <thead> <tr> <th class="param-name">Parameter</th> <th class="param-req">Required</th> <th class="param-desc">Description</th> </tr> </thead> <tbody> <tr class="request-param"> <td>expire_sessions</td> <td>Optional</td> <td class="param-desc"> <p>Set this to '1' if you want to end all of the user's Canvas web sessions. Without this argument, the endpoint will leave web sessions intact.</p> <p>Additionally, if the user logged in to Canvas via a delegated authentication provider, and the provider supports Single Log Out functionality, the response will contain a forward_url key. If you are still in control of the user's browsing session, it is recommended to then redirect them to this URL, in order to also log them out from where their session originated. Beware that it is unlikely that control will be returned to your application after this redirect.</p> </td> </tr> </tbody> </table> <h4>Example responses</h4> <pre class="example_code"> { "forward_url": "https://idp.school.edu/opaque_url" } </pre> </div>If your application needs to begin a normal web session in order to access features not supported via API (such as quiz taking), you can use your API access token in order to get a time-limited URL that can be fed to a browser or web view to begin a new web session.
<h3 class="endpoint">GET /login/session_token</h3> <h4>Parameters</h4> <table class="request-params"> <thead> <tr> <th class="param-name">Parameter</th> <th class="param-req">Required</th> <th class="param-desc">Description</th> </tr> </thead> <tbody> <tr class="request-param"> <td>return_to</td> <td>Optional</td> <td class="param-desc">An optional URL to begin the web session at. Otherwise the user will be sent to the dashboard.</td> </tr> </tbody> </table> <h4>Example responses</h4> <pre class="example code prettyprint"> { "session_url": "https://canvas.instructure.com/opaque_url" } </pre> </div>