In this quick guide, you'll learn how to authenticate from your app to your user's Night Zookeeper account and use that to retrieve data from the Night Zookeeper graphql API.
Note that we will only cover the authorization_code
flow from the OAuth 2.0 specs here.
You will first need to direct your user to our SSO portal hosted at https://oauth.nightzookeeper.com/oauth/login
This link will not work as it is. You will need to put parts of your App's credentials in the query parameters to make it work.
The first thing you will need is to put your clientId
as a query parameter named client_id
like so ?client_id=YOUR_CLIENT_ID
.
Then you will need to add the redirect uri that you specified when you got your NZK App registered. Let's imagine we specified these urls at creation:
During the testing phase, our query parameters would now look like this: ?client_id=YOUR_CLIENT_ID&redirect_uri=http://localhost:3000/myapp/login
Then you'll have to specify if you want to log in as a child by specifying type=student
. If you want to log in as an adult, you don't need the latter.
Our link would then be:
Whenever the user completed the form with correct credentials, we will redirect them back to the redirect URI you provided with a code
specified as the query parameter code
.
Example: http://localhost:3000/myapp/login?code=AUTHORIZATION_CODE
Now that you've successfully retrieved an authorization code, you will be able to use your client secret to get a token for this user.
For security reason, we highly recommend that you exchange the code for a token on a backend server to prevent leaking your client secret
in the front-end code.
You will need to perform the following request to get the token.
application/x-www-form-urlencoded
{{ clientId:clientSecret }} encoded in base64
{{ The authorization code from the previous step }}
'authorization_code'
(specific to this flow)Example using Axios:
const getToken = async () => {const params = new URLSearchParams()params.append('code', code)params.append('grant_type', 'authorization_code')const config = {headers: {'Content-Type': 'application/x-www-form-urlencoded','Authorization': `Basic ${window.btoa(`${clientId}:${clientSecret}`)}`}}try {const { data } = await Axios.post('https://oauth.nightzookeeper.com/oauth/token', params, config)// Use data} catch (err) {// Handle errorconsole.error(err.response ? error.response.data : err.message)}}
The data you receive will look something similar to this (excluding some extras):
{"user": {"_id": String,"username": String,"type": String,},"access_token": String,"refresh_token": String,"accessToken": String,"accessTokenExpiresAt": DateString,"refreshToken": String,"refreshTokenExpiresAt": DateString,"expiresInSeconds": Float}
From here, you'll get some basic info about the user (username
if student or email
if adult). You need to keep the accessToken
(access_token
is the same) and the refreshToken
.
You can now use that accessToken
to make queries on the Night Zookeeper GraphQL API.
Whenever the token gets expired (see accessTokenExpiresAt
), you use the refreshToken
to fetch a new token on the user's behalf.
Again, because this requires client credentials, please handle this flow on your backend.
You will need to perform the following request to get a fresh token.
application/x-www-form-urlencoded
{{ clientId:clientSecret }} encoded in base64
{{ The refresh token }}
'refresh_token'
(specific to this flow)Example using Axios:
const getNewToken = async () => {const params = new URLSearchParams()params.append('refresh_token', refreshToken)params.append('grant_type', 'refresh_token')const config = {headers: {'Content-Type': 'application/x-www-form-urlencoded','Authorization': `Basic ${window.btoa(`${clientId}:${clientSecret}`)}`}}try {const { data } = await Axios.post('https://oauth.nightzookeeper.com/oauth/token', params, config)// Use data} catch (err) {// Handle errorconsole.error(err.response ? error.response.data : err.message)}}
You can then use the accessToken
to query https://graphql.staging.nightzookeeper.com/graphql
or https://graphql.nightzookeeper.com/graphql
. Just set the Authorization header like this:
Authorization: Bearer ACCESS_TOKEN
You can use any GraphQL explorer (GraphiQL or Insomnia) to see the available data. A good start will be the following query:
query getStudentProfile {me {_idusernameavatar {url}countryCodegroup {_idname}animals(skip: 0, limit: 5) {_idnameartwork {url}}writings(skip: 0, limit: 5) {_idtitletext}}}
The query above would resolve the current user's avatar, group details, last 5 animals and last 5 writing. But there's so much more data you can start using! Let us know if you need help.