
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。
(1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
(2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。
(3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。
Four ways to get the token
- 授权码(authorization-code)
 
- 隐藏式(implicit)
 
- 密码式(password):
 
- 客户端凭证(client credentials)
 
A simple demo about third-party login
In config.js 
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | const GITHUB_OAUTH_URL = 'https://github.com/login/oauth/authorize' const SCOPE = 'user'
  const github = {     request_token_url: 'https://github.com/login/oauth/access_token',     client_id: '7719dcc449a12e7f83f4',     client_secret: '42771ea51b4a3afac6ab67cae5cd8b924f81c7fc', }
  module.exports = {     github,     GITHUB_OAUTH_URL,     OAUTH_URL: `${GITHUB_OAUTH_URL}?client_id=${github.client_id}&scope=${SCOPE}`, }
   | 
 
In server/auth.js 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
   |  const axios = require('axios') const config = require('../config')
  const { client_id, client_secret, request_token_url } = config.github
  module.exports = (server) => {     server.use(async (ctx, next) => {         if (ctx.path === '/auth') {             console.log(ctx.path)             const { code } = ctx.query             if (code) {                                  const result = await axios({                     method: 'POST',                     url: request_token_url,                     data: {                         client_id,                         client_secret,                         code,                     },                     headers: {                         Accept: 'application/json',                     },                 })
                                   if (result.status === 200 && (result.data && !result.data.error)) {                     ctx.session.githubAuth = result.data
                      const { access_token, token_type } = result.data                                          const { data: userInfo } = await axios({                         method: 'GET',                         url: 'https://api.github.com/user',                         headers: {                             Authorization: `${token_type} ${access_token}`,                         },                     })
                      ctx.session.userInfo = userInfo                                          ctx.redirect((ctx.session && ctx.session.urlBeforeOAuth) || '/')                     ctx.session.urlBeforeOAuth = ''                 } else {                     ctx.body = `request token failed ${result.data && result.data.error}`                 }             } else {                 ctx.body = 'code not exist'             }         } else {             await next()         }     }) }
 
  |