preface
We usually log in to different platforms, there will always be the use of Token scenarios, such as using github account to log in to the nuggets, at this time we will not give our Github account password to the nuggets, OAuth is such a mechanism, used for a variety of non-secret authorization login scenarios, in the convenience of ensuring security. In fact, it is to apply for token authorization to the platform. Recently, I used Spotify API to develop my own application, so I also encountered user authentication login scenario, stomp pits quite a lot, also learned a lot, so sorted out, I hope to help you 🤗.
Brief authorization process
- After the user opens the client, the client asks the user for authorization (gold login option: Github login).
- The user agrees to authorize the client (I click on Github and login is successful).
- The client uses the authorization obtained in the previous step to apply for a token (nuggets request access_token) from the authentication server.
- After the authentication server authenticates the client, github agrees to issue the access_token to the client.
- The client uses the token to request resources from the resource server (the nuggets take the access_token in exchange for resources).
- The resource server confirms that the token is correct and agrees to open the resource to the client (Github check pass).
The Nuggets and Github have a brief example to help you understand, and I’ll use Spotify for a detailed example
Authorization Code
Your site needs to be authorized by the server, and the corresponding developer needs to apply for an account, a secret key, and a redirect address
- Client_id: We signed up with Spotify
- Client Secret: the Secret key soptify gives us
- Redirect_uri: A URL to which the authentication server redirects the client (typically loacalhost for local development)
- Response_type: Need you to give me a code
- State: Any value. The specification specifies the same value for both requests and returns
How do YOU apply for developer status on Spotify develope
Here’s how TO apply for Spotify developer status. For those who are not interested, here’s how I explained the authentication process of OAth.
- Create your application instance here
- Click after login
create a client id
Generate a dedicatedclient_id
andclient_secret
.
- At the same time set up
Redirect URIs
, this is the address of the authenticated redirect, the port on which your application runs, be sure to fill in accurately.
-
Before applying for authorization, determine which permissions the application requires and declare them in the background parameters during authorization.
Spotify breaks down the permissions in detail, and the full permissions are as follows:
The licensing process on soptify’s website
The Authentication authorization
The ultimate purpose of authorization is to obtain a value named access_token, and then use this access_token to obtain various sample API information.
In order to strictly distinguish different uses and permissions, Spotify divides the access_token acquisition method into three processes, with different permissions and duration.
The characteristics of the three processes are as follows:
Authorization Code Flow
: Standard method to refresh tokensClient Credentials Flow
: App-level token, which cannot obtain user behaviors.Implicit Grant Flow
: Temporary authorization. Can get user behavior, not refresh. Short lives.
If there is no user click authorization, only the latter two authorization modes can be used. Only after the user clicks Authorization, can the user’s behavior seed be obtained for personalized development, which is also the recommended Authorization mode for developers. Then comes the Authorization Code process:
- to
/authorize
Send a GET request, the request header includesclient_id
andredirect_uri
Etc. - the
/authorize,accounts
Judge to be validclient_id
.redirect_uri
.client_secret
After that, Spotify pops up and the user manually logs in and clicks Permit - Spotify redirects the page to its own callback url and transmits one in clear text
Code
code - with
Code
Code to/token
Send a POST request and include a dynamically generated Base64 encoded one in the headerAuthorization
The value is a string in the format ofAuthorization: Basic *<base64 encoded client_id:client_secret>*
- Get access tokens from Spotify
access_token
And update the tokenrefresh_token
(Double token) - After obtaining the authorization code acess_token, the request header is added every time the browser requests resources
Authorization
field - in
access_token
The request server will return the 401 status code. In this case, the refresh token will be used to update the token: userefresh_token
to/token
Send a POST request to get a new oneaccess_token
.
😵 sounds a little meandering, but in fact, it authorizes third-party applications to access the service provider’s resources according to the OAuth 2.0 standard protocol, which is common in single sign-on (SSO) scenarios.
OAuth2.0 protocol, then we began to write code ~🤗
coding
First of all, our application process needs to obtain client_ID and client_secret, which must not be written in the code. We can write temporary environment variables on the local terminal, and read the ID and secret key through the Node process module process.
The Process object is a global variable that provides information that controls the current Node.js process. As an object, it is always available to Node.js applications, so require() is not required.
How does the Node process write environment variables? Here are two ways to configure temporary environment variables
Configure Node environment variables
- Windows configuration temporary CMD view environment variables, add environment variables, delete environment variables
# Check environment variables
set SPOTIFY_CLIENT_ID
Add an environment variable if it doesn't exist
set SPOTIFY_CLIENT_ID=XXXX
set SPOTIFY_CLIENT_SECRET=YYYY
Set variable name =% %; Variable content (your app's pathname)
setpath=%path%; C:\web; C:\Tools# delete environment variable ()
set SPOTIFY_CLIENT_ID=
set SPOTIFY_CLIENT_SECRET=
Copy the code
The Window CMD environment diagram is here
Check to see if it exists
$env:SPOTIFY_CLIENT_ID
Add an environment variable if it doesn't exist
$env:SPOTIFY_CLIENT_ID="XXX"
$env:SPOTIFY_CLIENT_SECRET="YYY"
Append values to environment variables
$env:path=$env:path + "; C:\web; C:\Tools"
Delete the environment variable del env:SPOTIFY_CLIENT_ID
Display all environment variables ls env:
Copy the code
Powershell figure in it
SPOTIFY_CLIENT_ID="XXX"
SPOTIFY_CLIENT_ID="YYY"
REDIRECT_URI can be used to read the account and key information in node through process.env.redirect_uri, and then the various interfaces required for back-end write authentication
First on an official website authorization flow chart, feel the authorization process 🧐
The login
/login
The login
let redirect_uri =
process.env.REDIRECT_URI ||
'http://localhost:8888/callback'
app.get('/login'.function(req, res) {
res.redirect('https://accounts.spotify.com/authorize?' +
querystring.stringify({
response_type: 'code',
client_id: process.env.SPOTIFY_CLIENT_ID,
scope: 'user-read-private user-read-email user-read-recently-played user-top-read user-follow-read user-follow-modify playlist-read-private playlist-read-collaborative playlist-modify-public',
expires_in: 3600,
redirect_uri
}))
})
Copy the code
The scope here looks at write, and it can configure any permissions it needs. The more permissions it has, the more user resources it can access. Users can click authorization to log in and delete authorization on the official website link.
access_token
- callback
app.get('/callback'.function(req, res) {
let code = req.query.code || null
let authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri,
grant_type: 'authorization_code',
expires_in: 3600
},
headers: {
'Authorization': 'Basic ' + (new Buffer(
process.env.SPOTIFY_CLIENT_ID + ':' + process.env.SPOTIFY_CLIENT_SECRET
).toString('base64'))
},
json: true
}
request.post(authOptions, function(error, response, body) {
if(! error && response.statusCode === 200){ var access_token = body.access_token var expires_in = body.expires_inlet uri = process.env.FRONTEND_URI || 'http://localhost:3000'
res.redirect(uri + '? access_token=' + access_token +'? expires_in=' + expires_in)
} else {
res.redirect(`/#${querystring.stringify({ error: 'invalid_token' })}`);}})})Copy the code
If the parameters are correct, the response packet format is:
If the parameters are correct, the server returns a JSON text containing the following parameters:
- Access_token: Access Token to be obtained.
- Expires_in: specifies the validity period of the Access Token, in seconds.
- Refresh_token: Refresh Token used to Refresh Access tokens.
- Scope: Access Token Indicates the final Access scope of the Token, that is, the list of permissions actually granted by the user. When the user authorizes the page, the user may cancel the permission on some requests.
- Cookies: let the browser remember the client, including session_id
The redirect_URL is automatically redirected to the redirect_URL, which is running on the React app. Now that I have the authentication, I can use the user information and access the Spotify API
Timeout refresh_token
“Refresh_token” as its name implies, “refresh_token” is used to refresh the token to avoid users clicking authorization again for authentication. So how can “refresh_token” and “access_token” be used together?
If we encounter an expired access_token, then we need to use refresh_token to get a new access_token. Sounds simple, but what if refresh_token also expires? Does the user need to log in again? The solution provided on the official website is simple: use **refresh_token to extend the validity of access_token. That’s coordinating double tokens
The correct way is that both tokens have their own expiration time, because the access_token needs to be refreshed, so the expiration time of refresh_token is longer than the access_token. So how do you keep refresh_token from expiring? After refreshing the access_token with refresh_token, we send the POST request to the Accounts service/API/Token endpoint, Grant_type specifies “refresh_token” so Spotify will return a new access_token. The new refresh_token is also returned, so the time for both tokens is extended again. This ensures that users can enjoy an unobserved refresh experience whenever they visit the application during a specified period of time.
app.get('/refresh_token'.function(req, res) {
// requesting access token from refresh token
const refresh_token = req.query.refresh_token;
let authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: {
'Authorization': `Basic` + (new Buffer(
process.env.SPOTIFY_CLIENT_ID + ':' + process.env.SPOTIFY_CLIENT_SECRET
).toString('base64')),
},
form: {
grant_type: 'refresh_token',
refresh_token,
},
json: true}; request.post(authOptions,function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token;
res.send({ access_token });
}
});
});
Copy the code
Axios makes a specific request
Because every time I make a request to the server, Request header needs to bring the authorization so in our front application through the window. The location. The href. Match (/ access_token = (/ ^ & *) /) to get the token Window. The location. The href. Match (/ expires_in = (*) [/ w] / [1] to the expiration date
. The rest of the required parameters are matched by themselves and then configured by AXIOS
headers: {
'Authorization': `Bearer ${access_token}`,}Copy the code
You can send a request to get data ~ 🤭
GIF demo specific process 👇
The last
This is a complete record of my OAuth2 authentication login, (found quite a lot of information to describe the complete process is very few, step on quite a lot of pits, so their own hands wrote a complete ~)
╰(* °▽ * *), thank you very much for seeing here, HOPE this article can help you gain something, this article uses The Open API of Spotify for example, it doesn’t matter if you don’t play Spotify, I believe you can also understand the OAth2 authentication process from this article, the code word is not easy, I hope you like 🥰
Some screenshots of this article are from
Generally the developer’s official website