乐趣区

关于javascript:从零搭建-Nodejs-企业级-Web-服务器七认证登录

认证登录过程

认证登录就是通过第三方受权来甄别用户信息的登录形式,比方:微信扫码登录。目前最为宽泛承受的受权规范是 OAuth2.0,基于 OAuth2.0 的认证登录实质上是 Web 利用在用户受权下获取该用户在第三方利用上的个人信息的过程:

对于 passport

OAuth2.0 定义了框架但具体实现依据厂商不同多少存在差别,而 passport 模块提供了抹平这种差别的机制,通过接入不同的 strategy 对象能够对接不同的第三方登录。本章将基于上一章已实现的工程 host1-tech/nodejs-server-examples – 06-session 接入 passport 模块实现 Github 认证登录。先在工程根目录装置 passport 与 passport-github:

$ yarn add passport         # 本地装置 passport
# ...
info Direct dependencies
└─ passport@0.4.1
# ...

$ yarn add passport-github  # 本地装置 passport-github
# ...
info Direct dependencies
└─ passport-github@1.1.0
# ...

加上 Github 认证登录

接下来在 Github 上新建 OAuth 利用:

而后加上 Github 登录形式:

// src/middlewares/auth.js
const passport = require('passport');
const {Strategy: GithubStrategy} = require('passport-github');

const GITHUB_STRATEGY_OPTIONS = {
  clientID: 'b8ada004c6d682426cfb',
  clientSecret: '0b13f2ab5651f33f879a535fc2b316c6c731a041',
  callbackURL: 'http://localhost:9000/api/login/github/callback',
};

const githubStrategy = new GithubStrategy(
  GITHUB_STRATEGY_OPTIONS,
  (accessToken, refreshToken, profile, done) => {
    /**
     * 依据 profile 查找或新建 user 信息
     */
    const user = {};
    done(null, user);
  }
);

passport.use(githubStrategy);

passport.serializeUser((user, done) => {
  /**
   * 依据 user 信息获取 userId
   */
  const userId = '46e5';
  done(null, userId);
});

passport.deserializeUser((userId, done) => {
  /**
   * 依据 userId 获取 user 信息
   */
  const user = {};
  done(null, user);
});

module.exports = function authMiddleware() {return [passport.initialize(), passport.session()];
};

Object.assign(module.exports, { passport});
// src/middlewares/index.js
const {Router} = require('express');
const cookieParser = require('cookie-parser');
const sessionMiddleware = require('./session');
const urlnormalizeMiddleware = require('./urlnormalize');
const loginMiddleware = require('./login');
+const authMiddleware = require('./auth');

const secret = '842d918ced1888c65a650f993077c3d36b8f114d';

module.exports = async function initMiddlewares() {const router = Router();
  router.use(urlnormalizeMiddleware());
  router.use(cookieParser(secret));
  router.use(sessionMiddleware(secret));
  router.use(loginMiddleware());
+  router.use(authMiddleware());
  return router;
};
// src/middlewares/login.js
const {parse} = require('url');

module.exports = function loginMiddleware(
  homepagePath = '/',
  loginPath = '/login.html',
  whiteList = {'/500.html': ['get'],
    '/api/health': ['get'],
    '/api/login': ['post'],
+    '/api/login/github': ['get'],
+    '/api/login/github/callback': ['get'],
  }
) {//...};
// src/controllers/login.js
const {Router} = require('express');
+const {passport} = require('../middlewares/auth');

class LoginController {
+  homepagePath;
+  loginPath;
+
  async init() {const router = Router();
    router.post('/', this.post);
+    router.get(
+      '/github',
+      passport.authenticate('github', { scope: ['read:user'] })
+    );
+    router.get(
+      '/github/callback',
+      passport.authenticate('github', {
+        failureRedirect: this.loginPath,
+      }),
+      this.getGithubCallback
+    );
    return router;
  }

  post = (req, res) => {
    req.session.logined = true;
-    res.redirect('/');
+    res.redirect(this.homepagePath);
  };
+
+  getGithubCallback = (req, res) => {
+    req.session.logined = true;
+    res.redirect(this.homepagePath);
+  };
}

-module.exports = async () => {+module.exports = async (homepagePath = '/', loginPath = '/login.html') => {const c = new LoginController();
+  Object.assign(c, { homepagePath, loginPath});
  return await c.init();};
<!-- public/login.html -->
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <form method="post" action="/api/login">
      <button type="submit"> 一键登录 </button>
    </form>
+    <a href="/api/login/github"><button>Github 登录 </button></a>
  </body>
</html>

拜访 http://localhost:9000/login.html 即可体验 Github 认证登录逻辑:

须要留神因为 Github 服务器在海内,偶然会呈现网络不通导致的认证异样,此时只有稍等一段时间再试就能够了。另外,登录过的读者能够通过革除 Cookie 重置登录状态。

本章源码

host1-tech/nodejs-server-examples – 07-authentication

更多浏览

从零搭建 Node.js 企业级 Web 服务器(零):动态服务
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
从零搭建 Node.js 企业级 Web 服务器(二):校验
从零搭建 Node.js 企业级 Web 服务器(三):中间件
从零搭建 Node.js 企业级 Web 服务器(四):异样解决
从零搭建 Node.js 企业级 Web 服务器(五):数据库拜访
从零搭建 Node.js 企业级 Web 服务器(六):会话
从零搭建 Node.js 企业级 Web 服务器(七):认证登录

退出移动版