Using Ion OAuth
The ultimate guide to OAuth authentication through Ion.
You can create and manage OAuth applications at https://ion.tjhsst.edu/oauth/applications.

What is Ion OAuth?

With the Django OAuth Toolkit, Ion supports accessing API and other resources via OAuth2. This allows for applications to be written using the Ion API without the need to prompt for user credentials from within the application. Instead, access tokens are used to gain access to Ion API resources. This functionality enables you to have users authenticate to your website using their Ion account. This is especially useful for apps that are meant to serve the TJ community.

Register an Application

Go into OAuth Management on Ion and click Create Application. Specify the following values in the form:
    Name
      Some descriptive name for your application.
    Client Type
      Choose Confidential if your app has a backend component and your server can store the client ID and secret securely.
      Choose Public if your app is purely client-side and a copy of the credentials will be distributed publicly.
    Authorization Grant Type
      Choose Authorization code if your client type is Confidential.
      Choose Implicit if your client type is Public.
    Redirect URIs
      Enter one or more URLs that your application will redirect back to after the authorization is complete.
    Algorithm
      If this option exists, leave it at the default No OIDC support. Ion doesn't support OpenID.

Requesting Authorization

Inside your application, redirect to the OAuth authorization endpoint to receive an authorization code. The url is https://ion.tjhsst.edu/oauth/authorize/. To access the API, exchange this code for a (temporary) access token. The URL is https://ion.tjhsst.edu/oauth/token/.

Python

python-social-auth + Django

If you want to use python-social-auth, a plugin is available in the ion_oauth package. You can get an older version here or download an updated version directly from GitHub here. For a Django project add AUTHENTICATION_BACKENDS = ['ion_oauth.oauth.IonOauth2'] and define SOCIAL_AUTH_ION_KEY and SOCIAL_AUTH_ION_SECRET in your settings.py file. The redirect_uris for Django projects should be "http://<site-url>/complete/ion/" and "http://<site-url>/complete/ion".

API Requests

For a Python client, use requests with requests-oauthlib. If running locally (without HTTPS), override the SSL requirement for OAuth2.
1
import os
2
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
Copied!
Create an OAuth2Session, with the CLIENT_ID and REDIRECT_URI you entered in the application form. Redirect the user to authorization_url.
1
from requests_oauthlib import OAuth2Session
2
oauth = OAuth2Session(CLIENT_ID,
3
redirect_uri=REDIRECT_URI,
4
scope=["read","write"])
5
authorization_url, state = oauth.authorization_url("https://ion.tjhsst.edu/oauth/authorize/")
Copied!
The user authenticates, approves the request, and is redirected to the callback URL specified in redirect_uri, with a "code" GET parameter.
1
token = oauth.fetch_token("https://ion.tjhsst.edu/oauth/token/",
2
code=CODE,
3
client_secret=CLIENT_SECRET)
4
print(token)
5
{'refresh_token': 'XXX', 'access_token': 'XXX', 'expires_in': 36000, 'expires_at': 1455370143.573362, 'scope': ['read', 'write'], 'token_type': 'Bearer'}
Copied!
At this point, a valid access token has been gained, and you can request API resources.
1
try:
2
profile = oauth.get("https://ion.tjhsst.edu/api/profile")
3
except TokenExpiredError as e:
4
args = { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET }
5
token = oauth.refresh_token("https://ion.tjhsst.edu/oauth/token/", **args)
6
7
import json
8
print(json.loads(profile.content.decode()))
9
{ 'ion_username': '2016jwoglom', ... }
Copied!
After 36,000 seconds (1 hour), the token will expire; you need to renew it. This can be handled by putting API commands inside a try-except for a oauthlib.oauth2.TokenExpiredError, such as seen above. Alternatively, you can provide auto_refresh_url=refresh_url, auto_refresh_kwargs=args as additional arguments to OAuth2Session when it is created.
1
args = { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET }
2
token = oauth.refresh_token("https://ion.tjhsst.edu/oauth/token/", **args)
Copied!

Node.js

You can use the simple-oauth2 library to perform authentication. Below is some sample code.
Note: This code will not work out of the box. Read the comments carefully to determine how to integrate it into your application.
1
var simpleoauth2 = require("simple-oauth2");
2
3
// make sure these variables are set
4
var ion_client_id = process.env.ION_CLIENT_ID;
5
var ion_client_secret = process.env.ION_CLIENT_SECRET;
6
var ion_redirect_uri = process.env.ION_REDIRECT_URI;
7
8
var oauth = simpleoauth2.create({
9
client: {
10
id: ion_client_id,
11
secret: ion_client_secret
12
},
13
auth: {
14
tokenHost: 'https://ion.tjhsst.edu/oauth/',
15
authorizePath: 'https://ion.tjhsst.edu/oauth/authorize',
16
tokenPath: 'https://ion.tjhsst.edu/oauth/token/'
17
}
18
});
19
20
// 1) when the user visits the site, redirect them to login_url to begin authentication
21
var login_url = oauth.authorizationCode.authorizeURL({
22
scope: "read", // remove scope: read if you also want write access
23
redirect_uri: ion_redirect_uri
24
});
25
26
// 2) on the ion_redirect_uri endpoint, add the following code to process the authentication
27
var code = req.query["code"]; // GET parameter
28
oauth.authorizationCode.getToken({code: code, redirect_uri: ion_redirect_uri}).then((result) => {
29
const token = oauth.accessToken.create(result);
30
31
// you will want to save these variables in your session if you want to make API requests
32
var refresh_token = token.token.refresh_token;
33
var access_token = token.token.access_token;
34
var expires_in = token.token.expires_in;
35
36
// log the user in
37
});
38
39
// 3) when making an API request, add the following header:
40
// Authorization: Bearer {{ INSERT ACCESS TOKEN }}
41
42
// 4) to refresh the access_token, use the following code
43
var token = oauth.accessToken.create({
44
"access_token": access_token,
45
"refresh_token": refresh_token,
46
"expires_in": expires_in
47
});
48
49
if (token.expired()) {
50
token.refresh((err, result) => {
51
token = result;
52
// the new access token
53
var access_token = token.token.access_token;
54
});
55
}
Copied!
Last modified 1mo ago