OAuth2
OAuth2 is a protocol designed to let third-party applications authenticate to perform actions as a user, without getting the user's password. Canvas uses OAuth2 (specifically RFC-6749) for authentication and authorization of the Canvas API.
- Storing Tokens
- Manual Token Generation
- Oauth2 Flow
- Using an Access Token to authenticate requests
- Using a Refresh Token to get a new Access Token
- Logging Out
- Endpoints
Storing Tokens
When appropriate, applications should store the token locally, rather than requesting a new token for the same user each time the user uses the application. If the token is deleted or expires, the application will get a 401 Unauthorized error from the API, in which case the application should perform the OAuth flow again to receive a new token. You can differentiate this 401 Unauthorized from other cases where the user simply does not have permission to access the resource by checking that the WWW-Authenticate header is set.
Storing a token is in many ways equivalent to storing the user's password, so tokens should be stored and used in a secure manner, including but not limited to:
- Don't embed tokens in web pages.
- Don't pass tokens or session IDs around in URLs.
- Properly secure the database or other data store containing the tokens.
- For web applications, practice proper techniques to avoid session attacks such as cross-site scripting, request forgery, replay attacks, etc.
- For native applications, take advantage of user keychain stores and other operating system functionality for securely storing passwords.
Manual Token Generation
For testing your application before you've implemented OAuth, the simplest option is to generate an access token on your user's profile page. Note that asking any other user to manually generate a token and enter it into your application is a violation of Canvas' terms of service. Applications in use by multiple users **MUST* use OAuth to obtain tokens*.
To manually generate a token for testing:
- Click the "profile" link in the top right menu bar, or navigate to
/profile
- Under the "Approved Integrations" section, click the button to generate a new access token.
- Once the token is generated, you cannot view it again, and you'll have to generate a new token if you forget it. Remember that access tokens are password equivalent, so keep it secret.
Oauth2 Flow
Your application can rely on canvas for a user's identity. During step 1 of the web application flow below, specify the optional scope parameter as scope=/auth/userinfo. When the user is asked to grant your application access in step 2 of the web application flow, they will also be given an option to remember their authorization. If they grant access and remember the authorization, Canvas will skip step 2 of the request flow for future requests.
Canvas will not give a token back as part of a userinfo request. It will only provide the current user's name and id.
Getting OAuth2 Client ID/Secret
If your application will be used by others, you will need to implement the full OAuth2 token request workflow, so that you can request an access token for each user of your application.
Performing the OAuth2 token request flow requires an application client ID and client secret. To obtain these application credentials, you will need to register your application. The client secret should never be shared.
For Canvas Cloud (hosted by Instructure), developer keys are issued by the admin of the institution.
NOTE for LTI providers: Since developer keys are scoped to the institution they are issued from, tool providers that serve multiple institutions should store and look up the correct developer key based on the launch parameters (eg. custom_canvas_api_domain) sent during the LTI launch.
For open source Canvas users, you can generate a client ID and secret in the Site Admin account of your Canvas install.
Step 1: Redirect users to request Canvas access
A basic request looks like:
GET https://<canvas-install-url>/login/oauth2/auth?client_id=XXX&response_type=code&redirect_uri=https://example.com/oauth_complete&state=YYY
See GET login/oauth2/auth for details.
Step 2: Redirect back to the request_uri, or out-of-band redirect
If the user accepts your request, Canvas redirects back to your request_uri with a specific query string, containing the OAuth2 response:
http://www.example.com/oauth2response?code=XXX&state=YYY
The app can then extract the code, and use it along with the client_id and client_secret to obtain the final access_key.
If your application passed a state parameter in step 1, it will be returned here in step 2 so that your app can tie the request and response together.
If the user doesn't accept the request for access, or if another error
occurs, Canvas redirects back to your request_uri with an error
parameter, rather than a code
parameter, in the query string.
If the user doesn't accept the request for access, or if another error
occurs, Canvas will add an error
parameter, rather than a code
parameter, to the query string.
http://www.example.com/oauth2response?error=access_denied
access_denied
is the only currently implemented error code.
Note for native apps
Canvas redirects to a page on canvas with a specific query string, containing parameters from the OAuth2 response:
/login/oauth2/auth?code=<code>
/login/oauth2/auth?code=<code>
At this point the app should notice that the URL of the webview has
changed to contain code=<code>
somewhere in the query
string. The app can then extract the code, and use it along with the
client_id and client_secret to obtain the final access_key.
Step 3: Exchange the code for the final access token
To get a new access token and refresh token, send a POST request to login/oauth2/token with the following parameters:
Parameters
Parameter | Value |
---|---|
grant_type | authorization_code |
client_id | Your client_id |
client_secret | Your client_secret |
redirect_uri | If a redirect_uri was passed to the initial request in step 1, the same redirect_uri must be given here. |
code | code from canvas |
Using an Access Token to authenticate requests
Once you have an OAuth access token, you can use it to make API requests. If possible, using the HTTP Authorization header is recommended.
OAuth2 Token sent in header:
curl -H "Authorization: Bearer <ACCESS-TOKEN>" "https://canvas.instructure.com/api/v1/courses"
Sending the access token in the query string or POST parameters is also supported, but discouraged as it increases the chances of the token being logged or leaked in transit.
OAuth2 Token sent in query string:
curl "https://canvas.instructure.com/api/v1/courses?access_token=<ACCESS-TOKEN>"
Using a Refresh Token to get a new Access Token
Access tokens have a 1 hour lifespan. When the refresh flow is taken, Canvas will update the access token to a new value, reset the expiration timer, and return the new access token as part of the response. When refreshing tokens the user will not be asked to authorize the application again.
To refresh the access token, send a POST request to login/oauth2/token with the following parameters:
Parameters
Parameter | Value |
---|---|
grant_type | refresh_token |
client_id | Your client_id |
client_secret | Your client_secret |
refresh_token | refresh_token from initial access_token request |
The response to this request will not contain a new refresh token; the same refresh token is to be reused.
Logging Out
To logout, simply send a DELETE request to login/oauth2/token