基于 Express
OAuth(开放授权)是一个开放标准, 允许用户授权第三方应用访问他们存储在另外的服务提供者 (如 QQ, 微信) 上的信息, 而不需要将用户名和密码提供给第三方应用或分享他们数据的所有内容
GitHub 授权登录
GitHub 提供的是标准授权代码授予类型
OAuth 的更多知识可以移步阮一峰的博客
授权码模式 (authorization code) 是功能最完整, 流程最严密的授权模式. 它的特点就是通过客户端的后台服务器, 与 "服务提供商" 的认证服务器进行互动
授权登录流程图
image
申请一个 OAuth App
首先我们必须登录上 GitHub 申请一个 OAuth App, 步骤如下:
登录 GitHub
点击头像下的 Settings -> Developer settings 右侧 New OAuth App
填写申请 auth 的相关配置, 重点配置项有 2 个
Homepage URL 这是后续需要使用授权的 URL , 你可以理解为就是你的项目根目录地址
*Authorization callback URL 授权成功后的回调地址, 这个至关重要, 这是拿到授权 code 时给你的回调地址.
具体操作如下
image.PNG
image
image
image
代码实现
GitHub 官方文档
项目目录结构
image
安装
- NPM install passport
- NPM install express-session
- NPM install passport-GitHub
持久化用户登录
passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(obj, done) { done(null, obj); });
添加中间件
App.use(session({ secret: 'sessionsecret' })); App.use(passport.initialize()); App.use(passport.session());
我们点击 GitHub 登录, 发送请求 http:// 域名 / auth/GitHub 到自己的服务器里, 然后后端收到这个请求就会去向 GitHub 发送认证
router.get('/github',passport.authenticate('github'));
当 GitHub 认证成功后就会发送一个 callback 到我们的服务器, 这个时候会传给我们一系列该用户的数据. 然后后端可以把用户的信息保存到 session 里
router.get('/github/callback', passport.authenticate('github', { failureRedirect: '/login' }), function(req, res) { req.session.user = { id: req.user.id, username: req.user.displayName || req.user.username, avatar: req.user._json.avatar_url, provider: req.user.provider }; res.redirect('/'); });
当用户注销的时候, 发送 http:// 域名 / auth/logout 请求时, 后端接受后对 session 进行销毁
router.get('/logout', function(req, res){ req.session.destroy(); res.redirect('/'); })
配置 GitHub 的 clientID 和 clientSecret 这个还是比较简单的: 登录 GitHub - 进入设置 - 进入 developer settings - 新建 OAuth Apps. 配置好后, 后端写上:
passport.use(new GitHubStrategy({ clientID: 'xxxxxxxxxxxxxxx', clientSecret: 'xxxxxxxxxxxxxxxxxxxxxx', callbackURL: "http://xxxxxxxxxxx/auth/github/callback" }, function(accessToken, refreshToken, profile, done) { // User.findOrCreate({ githubId: profile.id }, function (err, user) { // }); done(null, profile); } ));
auth.JS
var express = require("express"); var router = express.Router(); var passport = require("passport"); var GitHubStrategy = require("passport-github").Strategy /* GET auth. */ passport.serializeUser(function(user, done) { console.log("serializeUser", user); done(null, user); }); passport.deserializeUser(function(obj, done) { console.log("deserializeUser", obj); done(null, obj); }); router.get("/logout", function(req, res) { req.session.destroy(); res.redirect("/"); }); router.get('/github', passport.authenticate('github')); passport.use( new GitHubStrategy( { clientID: "53a2b5af338b03ee60cc", clientSecret: "0ba96bcd7886dc99122b2c5c875440817d928ac7", callbackURL: "http://localhost:3000/auth/github/callback" }, function(accessToken, refreshToken, profile, done) { // User.findOrCreate({ githubId: profile.id }, function (err, user) { // }); done(null, profile); } ) ); router.get( "/github/callback", passport.authenticate("github", { failureRedirect: "/login" }), function(req, res) { req.session.user = { id: req.user.id, username: req.user.displayName || req.user.username, avatar: req.user._json.avatar_url, provider: req.user.provider }; res.redirect("/"); } ); module.exports = router;
来源: http://www.jianshu.com/p/061bbcae1f29