Authentication and Authorization
Authentication
Authentication is how to prove that you are yourself, and generally the way to prove that you are yourself is through id cards; Authentication on the Internet usually uses a username and password to prove that you are yourself. Common identity authentication methods are as follows:
- Login with username and password
- Email sends login link
- Mobile phone number Receiving verification code
Authorization
For example, when you install a mobile application, the application will apply for permission. If you agree to this permission application process, it is called authorization. Similarly, in OAuth, the licensee gains certain permissions. Oauth is commonly used by:
The relationship between authorization and authentication
Authorization does not necessarily require authentication. For example: When you have a key, you can open the door, you are not necessarily the owner of the house. Oauth authorization on the Internet is usually granted by token.
OAuth
The concept of the request
OAuth is a standard authorization method in the Internet industry. Each company implements its own OAuth authentication and authorization process according to this set of standards, and third parties need to use OAuth to access this process. OAuth is currently available in two versions:
- 1. X (deprecated)
- 2. X (popular)
Role understanding
There are several roles in the OAuth third-party authentication and authorization process:
- Client: browser
- Server side: Develop the corresponding server side of this website
- Authorized server: provider of OAuth third-party access services, such as QQ and wechat.
Another way of saying this is that the client and the server can be combined as the authorized party. If you do a pure client-side OAuth access, then you can also do without the server, but this access method is not very secure.
Authorization way
At present, there are many ways of OAuth authorization in the industry, among which the most important ones are the following:
- Authorization Code (most commonly used)
- Refresh Token: Applies for a new authorization Token from the OAuth access party if the authorization Token has not expired
- Device Code: Applies to third-party access of smart TVS.
- Password: use the API exposed by OAuth to log in with the user name and Password of this website. (Not recommended, trust and security, generally used for internal login)
- Implicit: Obsolete
- Client Credentials
Authorization Code
The process for accessing OAuth through authentication and authorization codes is as follows:
- The client initiates a request
redirect
Go to OAuth access party and attachclient_id
- The user in
redirect
Enter your username and password on the next web site - After a successful login, the OAuth access party returns one to the server
code
. - Server side get
code
After that, take itclient_secret
andcode
Apply to OAuth access party for accessToken
- After obtaining the Token, the server enters the authorization window
- If the authorization succeeds, go to the client website.
Github OAuth Third-party access
Registered making request
url:https://github.com/settings/apps
- Log in making
- Click your picture, Setting
- Click on the developer setting
- New request App
Note: The URL of a HomePage should be filled with the root path of the local project before the project is launched and the domain name after the project is launched. Similarly Authorization callback URL before online fill out http://localhost:3000/auth, the online after fill in the domain name + / auth. After successful registration, a client_id and client_secret values appear, which are very important. It needs to be saved in a project file
OAuth field description
Jump field
Url: https://github.com/login/oauth/authorize param:
- Client_id: client_id is the client_id at registration time
- Scope: indicates the desired permission scope
- Redirect_uri: specifies the address to be redirected to the project after authorization. It must be the same as the address used when registering Github OAuth App
redirect uri
The same - Login: the specific account used to login and authorize applications. If you have logged in to github from that site and authorized it, you will not need to login to OAuth for this request.
- State: random string that cannot be guessed. It is used to prevent cross-site request forgery attacks.
- Allow_signup: Whether to provide the option to register GitHub to unauthenticated users in the OAuth process. The default value is true. False Used when the policy forbids registration.
The request token
Url: https://github.com/login/oauth/access_token param:
- Client_id: Required, specifying the token user
- Client_secret: Required, which indicates the token user
- Code: required, indicating that the user is authorized
- Redirect_uri: same as above
- State: same as above
Requesting user information
Url: https://api.github.com/user the header:
- Authorization: Specifies the access_token returned during access_token request
token +access_token
Github OAuth Authorization how to ensure security
strategy
- One-time code: The code returned after the authorization is successful is one-time. After the access_token request is made, the last code is invalid.
- Id + secret authentication: When requesting access_token, not only code is required, but also client_ID and client_secret are required. Even if the code has been leaked, as long as the other party does not have these two fields, it cannot obtain our access_token.
- Redirect_uri: This field is the URI returned when the request is made, if the field matches github’s
Authorization callback URL
If not, an error will be reported.
Use cookies and sessions to store tokens
After the user completes the OAuth process, the token is saved in the cookie and session, so that the user does not need to perform OAuth authentication and authorization every time he switches pages.
Store the cookies
How the KOA framework stores cookies:
server.use(async (ctx, next) => {
ctx.cookies.set('id', id, {
httpOnly: true
});
await next()
})
Copy the code
Store the session
const session = require('koa-session');
// Encrypt the cookie. The encrypted ciphertext is JWT
server.keys = ['ainuo develop github apps'];
const SESSION_CONFIG = {
// key is the name of the stored field
key: 'jid'.// When no store is configured, sessions are stored in cookies as JWT
// store:
};
// Use session middleware
server.use(session(SESSION_CONFIG, server));
// Generally we expose a separate interface for setting up sessions.
router.get('/set/user'.async ctx => {
/ / set the session
ctx.session.user = {
name: 'ainuo'.age: 18
};
ctx.body = 'set session success'
});
Copy the code
Store the token in Redis
Creating a Store object
This object was created to integrate Redis into KOS-session and to simplify redis operations
function getRedisSessionId(sessionId) {
return `ssid:${sessionId}`
}
module.exports = class RedisSessionStore {
constructor(client) {
this.client = client
}
// Get session data stored in Redis according to sessionId
async get(sessionId) {
console.log('get session', sessionId);
const id = getRedisSessionId(sessionId);
const data = await this.client.get(id);
if(! data) {return null
}
try {
return JSON.parse(data);
} catch (e) {
console.log(e)
}
}
// Store session data to Redis
async set(sessionId, sessionValue, lifetime) {
console.log('set session', sessionId);
const id = getRedisSessionId(sessionId);
if (typeof lifetime === "number") {
lifetime = Math.ceil(lifetime / 1000);
}
try {
const sessionStr = JSON.stringify(sessionValue);
if (lifetime) {
await this.client.setex(id, lifetime, sessionStr)
} else {
await this.client.set(id, sessionStr)
}
} catch (e) {
console.log(e)
}
}
// Delete a session from Redis
async destroy(sessionId) {
console.log('destroy session', sessionId);
const id = getRedisSessionId(sessionId);
await this.client.del(id)
}
}
Copy the code
Koa-session connects to the Redis database
const Redis = require('ioredis');
// Some configuration can be passed in
const client = new Redis({});
server.keys = ['ainuo develop github apps'];
const SESSION_CONFIG = {
key: 'jid'.// When no store is configured, sessions are stored in cookies as JWT
store: new RedisSessionStore(client),
// maxAge: 10 * 1000,
};
// Encrypt the session on the server
server.use(session(SESSION_CONFIG, server));
// Delete ssiD: XXX from redis database when deleting session
router.get('/del/user'.async ctx => {
/ / set the session
ctx.session = null;
ctx.body = 'del session success'
});
// Add session to redis database when setting session
router.get('/set/user'.async ctx => {
/ / set the session
ctx.session.user = {
name: 'ainuo'.age: 18
};
ctx.body = 'set session success'
});
Copy the code
Koa connects to Github OAuth
//config,js
module.exports = {
github: {
client_id: 'xxxx'.client_secret: 'xxxx'.request_token_url: 'https://github.com/login/oauth/access_token'.auth_url: 'https://github.com/login/oauth/authorize'.scope: 'user'.user_info_url: 'https://api.github.com/user'}};// auth.js
const axios = require('axios');
const {github} = require('.. /config');
const {client_id, client_secret, request_token_url} = github;
module.exports = function (server) {
server.use(async (ctx, next) => {
if (ctx.path === '/auth') {
const code = ctx.query.code;
if (code) {
// Initiate a request to access_token
const res = await axios({
method: 'POST'.url: request_token_url,
data: {
client_id,
client_secret,
code
},
headers: {
Accept: 'application/json',}});if (res.status === 200 && !(res.data && res.data.error)) {
ctx.session.githubAuth = res.data;
const {access_token, token_type} = res.data;
// Request user information
const userInfoRes = await axios({
method: 'GET'.url: github.user_info_url,
headers: {
Authorization: `token ${access_token}`}});// Store user information to session and redis
ctx.session.userInfo = userInfoRes.data;
// Redirect to the home page after the authorization process is complete
ctx.redirect('/');
} else {
const errorMsg = res.data && res.data.error;
ctx.body = `request token failed ${errorMsg}`}}else {
ctx.body = 'code not exist'; }}else {
await next()
}
})
};
// server.js
// Encrypt the session on the server
server.use(session(SESSION_CONFIG, server));
Github oauth login
auth(server);
Copy the code
The project address