Original address: http://www.moye.me/?p=592
What is OAuth?
OAuth (Open Licensing) is an open standard that allows a third-party app to access private resources (such as photos, videos, contact lists) that the user stores on a site without having to provide a user name and password to third-party apps.
OAuth 2.0
The OAuth versions are v1.0, v1.0a, and v2.0. The emergence of OAuth 2.0 is mainly to solve several problems in 1.0+, improve the ease of development and application security:
- Better support for non-browser apps (mobile and desktop client, can omit v1.0 Exchange token process, enhance the user experience)
- Added a renewal concept to the access token (access-token), a layer of defense against token leaks
- No more forcing clients to use token Secret, and having tokens is enough
- Introduction of bearer verification mechanism
OAuth 2 is currently a widely supported version, but is not backwards compatible with 1.0.
Terms
Simply put, OAuth 2 involves three-party
- Client APP: The program to access the user
- Resource Owner: User, licensed by him to the app
- Authorization Server: Also known as API Provider (Google/facebook/twitter ... )
- CLIENT_ID and Client_secret:server credentials issued to the APP
- Access Token:server issued a token that accesses the resource API needs to take it
- Scope:app provide the server with the kind of API that needs to be called
- Redirect Url:app The callback address provided to the server
OAuth 2 Interaction Model
The interactive model of OAuth 2 is flexible, and the main interaction models are divided into the following types:
- Server-Side Authorization Code authorization: widely adopted by Web service-side programming, is also the model highlighted in this paper
- Client-side implicit authorization: Web Client-side programming (JavaScript APP) interacts in this way and takes the token directly after the user authorizes it
- Resource Owner Login Authorization: Requires the user to enter a user name and password to exchange tokens
- Client credentials: In this model, the APP may be owner, making API calls on its own
Preparatory work
First, developers need to go to API provider, create app information for app, request permission, take Google as an example:
- Create a project in Google developers Console
- In APIs & Auth-in APIs, choose to open the API that needs to be called
- In APIs & Auth-Credentials, fill in the Redirect URIS (the address of the OAuth 2 callback) to create the client ID. After success, you will get the required client ID and client SECRET, keep it to yourself.
- In APIs & Auth-Consent screen, fill in the app meta-information such as Email/product Name/homepage/logo, which are presented to the user and appear on the confirmation authorization page during the interactive process.
Service-Side interaction process
The service-side interaction process for OAuth 2 is a transparent tripartite process for users:
If you use node. js to implement the aforementioned Google API OAuth 2 access, the programming model is probably the same:
- Do you know if you have access_token and have expired? If it does not exist or expires, step-by:
- Jump the user page to Https://accounts.google.com/o/oauth2/auth (enclose a series of query parameters: Response_type/client_id/redirect_uri/scope, Append parameters as needed: access_type/approval_prompt/state ... )
- Provides processing of the HTTP GET method for Redirect_uri in response to callbacks
- The callback for the 3rd step receives a code parameter that initiates a POST request with the parameters required: Code/client_id/client_secret/redirect_uri/grant_type
- Provides processing of the HTTP GET method for the Redirect_uri of step 4th in response to callbacks
- The 5th step callback will receive a JSON object with Access_token and its expiration time expires_in, save it
- Access the API and attach the resulting access_token
Introducing a Passport
Obviously, the implementation of the OAuth process will need to write a lot of things, and each additional API Provider, this process needs to come again. There's a slang in this line: the more you write, the more you're wrong. This time, we should find a suitable framework
The Passport framework is designed to solve similar problems: it provides identity authentication for node programs in the form of middleware, and the framework itself encapsulates the general form of the authentication process (Basic & Digest/oauth/open ID), callbacks, and error handling. and the specific certification implementation is abstracted as strategy (strategy), and the framework itself is not related, as long as the passport-compliant strategy can be added as a plug-in form of the project is used by Passport. For example, Google-based OAuth 2 certification, we can use Passport-google-oauth, based on Facebook's OAuth 2 certification we can use Passport-facebook, of course, can also use other or write their own. This policy-based abstraction is greater than simplifying the programming model, so passport has the confidence that "simple, unobtrusive authentication for node. js", Prudential does not bully me.
Passport for Google User Login
Google as a specific API Provider, with its passport OAuth 2 access, requires a strategy to achieve its interactive process implementation, in this case, the use of Passport-google-oauth
Determine the reference in Package.json and install the module with the NPM installation:
"dependencies": {
//... more libraries
"passport": "*",
"passport-google-oauth": "*",
}
Save the client_id and Client_secret from Google developers Console to the configuration file:
{
//...more configuration
"GOOGLE_CLIENT_ID" : "xxxx.apps.googleusercontent.com",
"GOOGLE_CLIENT_SECRET" : "wdsfas3_-safdsafasf",
"GOOGLE_RETURN_URL" : "http://www.xxx.com/auth/google/return",
}
The configuration class Configutils mentioned in the previous article will be able to read it automatically, combining these to implement the Google OAuth 2 certification (authutils.js:
var passport = require(‘passport‘)
, GoogleStrategy = require(‘passport-google-oauth‘).OAuth2Strategy;
var config = require(‘../configUtils‘);
passport.use(new GoogleStrategy({
authorizationURL: ‘https://accounts.google.com/o/oauth2/auth‘,
tokenURL: ‘https://accounts.google.com/o/oauth2/token‘,
clientID: config.getConfigs().GOOGLE_CLIENT_ID,
clientSecret: config.getConfigs().GOOGLE_CLIENT_SECRET,
callbackURL: config.getConfigs().GOOGLE_RETURN_URL
},
function (accessToken, refreshToken, profile, done) {
var userInfo = {
‘type‘: ‘google‘,
‘userid‘: profile.id,
‘name‘: profile.displayName,
‘email‘: profile.emails[0].value,
‘avatar‘: profile._json.picture
};
return done(null, userInfo);
}
passport.serializeUser(function (user, done) {
done(null, user);
});
passport.deserializeUser(function (obj, done) {
done(null, obj);
});
));
The function in the code (Accesstoken, Refreshtoken, profile, done) is the callback after the user authorizes, the Passport will wrap the obtained user information into the profile, the conversion code inside is free to play, Finally, remember to call done and return the user information. Done is the callback we define in the route, which we'll mention later.
Serializeuser and Deserializeuser are serialization/deserialization for conversion.
Combine Express
To export the route to Express in Authutils.js:
module.exports = function (app) {
app.use(passport.initialize());
app.get(‘/auth/google‘,
passport.authenticate(‘google‘, {
scope: ‘https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile‘
}));
app.get(‘/auth/google/return‘,
passport.authenticate(‘google‘, { failureRedirect: ‘/login‘ }),
function (req, res) {
if (req.user) {
//...some user login handling code
}
res.redirect(‘/‘);
});
};
The 1th get route is the address we can refer to on the UI, click it to start the OAuth 2 process, the Passport entry, the 2nd get route is the passport exit, the last section mentions the address of the done method callback, the entire OAuth 2 process is complete, the program gets The user information (the passport injects it into the req, but it is only available once and burned after reading). Any error occurred during the authentication process and will jump to the address specified by Failureredirect. Passport has done a series of trivial things like code exchange tokens for us.
App.js in the call, so easy:
var authutils = require ('.. /authutils '); authutils (app);
Summary
The OAuth 2 protocol provides a secure, open, and simple standard for the authorization of user resources, but even so, there is still a need to write a lot of code for Owner/app/server's three-party interaction process in node. JS's OAuth 2 interactive implementation. Using the Passport framework will greatly simplify this programming model, allowing us to devote more effort to business implementations.
This article provides only a passport-based framework of the OAuth 2 scenario thinking, the code part is only a skeleton, look at the point.
More articles please visit my blog new address: http://www.moye.me/
[node. js] OAuth 2 and the Passport framework