Express结合Passport实现登陆认证和Passport现实社交网络OAuth登陆

Express结合Passport实现登陆认证

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: [email protected]

转载请注明出处:
http://blog.fens.me/nodejs-express-passport/

前言

登陆认证,是每个应用都需要的基础功能。但很多的时候,却都被大家所忽略,不仅安全漏洞严重,而且代码紧耦合,混乱不堪。

Passport项目,正是为了解决登陆认证的事情,让认证模块更透明,减少耦合!

目录

  1. 什么是认证(Authentication)?
  2. Passport项目介绍
  3. Express结合Passport实现登陆认证

1. 什么是登陆认证(Authentication)?

认证又称“验证”、“鉴权”,是指通过一定的手段,完成对用户身份的确认。身份验证的方法有很多,基本上可分为:基于共享密钥的身份验证、基于生物学特征的身份验证和基于公开密钥加密算法的身份验证。

登陆认证,是用户在访问应用或者网站时,通过是先注册的用户名和密码,告诉应用使用者的身份,从而获得访问权限的一种操作。

几乎所有的应用都需要登陆认证!

2. Passport项目介绍

Passport项目是一个基于Nodejs的认证中间件。Passport目的只是为了“登陆认证”,因此,代码干净,易维护,可以方便地集成到其他的应用中。

Web应用一般有2种登陆认证的形式:

  • 用户名和密码认证登陆
  • OAuth认证登陆

Passport可以根据应用程序的特点,配置不同的认证机制。本文将介绍,用户名和密码的认证登陆。

项目网站:http://passportjs.org/

3. Express结合Passport实现登陆认证

系统环境:

  1. Win7 64bit 旗舰版
  2. node v0.10.5
  3. npm 1.2.19

1). 新建项目

D:\workspace\javascript>express -e
nodejs-passport

D:\workspace\javascript>cd nodejs-passport
&& npm install

D:\workspace\javascript\nodejs-passport>npm
install passport

D:\workspace\javascript\nodejs-passport>npm
install passport-local

2). 实现Session的认证:

  • 启用connet的session中间件
  • connet的session中间件,同时依赖于connect的cookieParser中间件
  • 配置passport中间件

关于connect框架的详细说明,请参考文章:Nodejs基础中间件Connect

修改app.js

app.use(express.cookieParser())

app.use(express.session({secret: ‘blog.fens.me‘,
cookie: { maxAge: 60000 }}));

app.use(passport.initialize());

app.use(passport.session());

3). 定义认证策略:

LocalStrategy策略,用于匹配本地环境的用户名和密码,可以扩展这个策略,通过数据库的方式进行匹配。

修改app.js

var passport = require(‘passport‘)

,
LocalStrategy = require(‘passport-local‘).Strategy;

passport.use(‘local‘, new LocalStrategy(

function (username, password, done) {

var
user = {

id: ‘1‘,

username: ‘admin‘,

password: ‘pass‘

};
// 可以配置通过数据库方式读取登陆账号

if
(username !== user.username) {

return done(null, false, { message: ‘Incorrect username.‘ });

}

if
(password !== user.password) {

return done(null, false, { message: ‘Incorrect password.‘ });

}

return done(null, user);

}

));

passport.serializeUser(function (user, done) {//保存user对象

done(null, user);//可以通过数据库方式操作

});

passport.deserializeUser(function (user, done)
{//删除user对象

done(null, user);//可以通过数据库方式操作

});

4). 路由控制和登陆认证

路由页面

  • /: 首页,用于登陆,未登陆用户只能访问首页
  • /login: 登陆请求,用户登陆时,POST到登陆请求,认证成功跳到用户页,认证失败回到首页
  • /users: 用户页,用户通过登陆认证后,可以访问用户页
  • /logout: 登出请求,用户退出系统,GET到登出请求,页面自动跳回首页

修改app.js

app.get(‘/‘, routes.index);

app.post(‘/login‘,

passport.authenticate(‘local‘, {

successRedirect: ‘/users‘,

failureRedirect: ‘/‘

}));

app.all(‘/users‘, isLoggedIn);

app.get(‘/users‘, user.list);

app.get(‘/logout‘, function (req, res) {

req.logout();

res.redirect(‘/‘);

});

function isLoggedIn(req, res, next) {

if
(req.isAuthenticated())

return next();

res.redirect(‘/‘);

}

5). 运行程序

运行日志

D:\workspace\javascript\nodejs-passport>node
app.js

Express server listening on port 3000

POST /login 302 389ms - 68b

GET /users 200 2ms - 50b

GET /logout 302 2ms - 58b

GET / 200 7ms - 540b

GET /stylesheets/style.css 304 6ms

POST /login 302 2ms - 58b

GET / 200 2ms - 540b

GET /stylesheets/style.css 304 2ms

6). 完整的代码

  • app.js代码
  • index.ejs代码
  • user.js代码

app.js代码

var express = require(‘express‘)

,
routes = require(‘./routes‘)

, user
= require(‘./routes/user‘)

, http
= require(‘http‘)

, path
= require(‘path‘)

, app =
express();

var passport = require(‘passport‘)

,
LocalStrategy = require(‘passport-local‘).Strategy;

app.set(‘port‘, process.env.PORT || 3000);

app.set(‘views‘, __dirname + ‘/views‘);

app.set(‘view engine‘, ‘ejs‘);

app.use(express.favicon());

app.use(express.logger(‘dev‘));

app.use(express.bodyParser());

app.use(express.methodOverride());

app.use(express.cookieParser())

app.use(express.session({secret: ‘blog.fens.me‘,
cookie: { maxAge: 60000 }}));

app.use(passport.initialize());

app.use(passport.session());

app.use(app.router);

app.use(express.static(path.join(__dirname,
‘public‘)));

if (‘development‘ == app.get(‘env‘)) {

app.use(express.errorHandler());

}

passport.use(‘local‘, new LocalStrategy(

function (username, password, done) {

var
user = {

id: ‘1‘,

username: ‘admin‘,

password: ‘pass‘

};
// 可以配置通过数据库方式读取登陆账号

if
(username !== user.username) {

return done(null, false, { message: ‘Incorrect username.‘ });

}

if
(password !== user.password) {

return done(null, false, { message: ‘Incorrect password.‘ });

}

return done(null, user);

}

));

passport.serializeUser(function (user, done) {//保存user对象

done(null, user);//可以通过数据库方式操作

});

passport.deserializeUser(function (user, done)
{//删除user对象

done(null, user);//可以通过数据库方式操作

});

app.get(‘/‘, routes.index);

app.post(‘/login‘,

passport.authenticate(‘local‘, {

successRedirect: ‘/users‘,

failureRedirect: ‘/‘

}));

app.all(‘/users‘, isLoggedIn);

app.get(‘/users‘, user.list);

app.get(‘/logout‘, function (req, res) {

req.logout();

res.redirect(‘/‘);

});

http.createServer(app).listen(app.get(‘port‘),
function () {

console.log(‘Express server listening on port ‘ + app.get(‘port‘));

});

function isLoggedIn(req, res, next) {

if
(req.isAuthenticated())

return next();

res.redirect(‘/‘);

}

index.ejs代码

<!DOCTYPE html>

<html>

<head>

<title><%= title %></title>

<link rel=‘stylesheet‘
href=‘/stylesheets/style.css‘ />

</head>

<body>

<h1>Login</h1>

<form action="/login"
method="post">

<div>

<label>Username:</label>

<input type="text"
name="username"/>

</div>

<div>

<label>Password:</label>

<input type="password" name="password"/>

</div>

<div>

<input type="submit" value="Log
In"/>

</div>

</form>

</body>

</html>

user.js代码

exports.list = function (req, res) {

var html = "<h2>你好,
" + req.user.username + "</h2><a href=‘/logout‘>退出</a>";

res.send(html);

};

通过Passport中间件,我们就把登陆认证和应用程序分离了出来,从而保证了更清晰代码结构。当然,我们也可不用Passport,在Express中直接实现登陆认证,可以参考文章:Nodejs开发框架Express3.0开发手记–从零开始

Passport现实社交网络OAuth登陆

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: [email protected]

转载请注明出处:
http://blog.fens.me/nodejs-oauth-passport/

前言

随着社交网络的发展,开发一个应用门槛越来越低。从一个完整的应用系统,到一个部署在社交网络平台的APP;从数据库–》应用层–》展示层,变成只需要开发展示层。

很多的社交应用,甚至都放弃了用户注册!仅靠大型社交网站的登陆授权,就可以赚到100W以上的用户量。。。

减少用户管理代码开发及维护,更专注于应用本身,个人开发者已经崛起!!

目录

  1. Passport介绍
  2. OAuth介绍
  3. 登陆Github
  4. 登陆LinkedIn

1. Passport介绍

Passport项目,主要是为了解决登陆认证的问题。

Web应用一般有2种登陆认证的形式:

  • 用户名和密码认证登陆
  • OAuth认证登陆

在上一篇文章中,我们介绍了Passport的项目,通过用户名和密码认证登陆。Express结合Passport实现登陆认证

本文将介绍,通过Passport实现OAuth登陆认证。

2. OAuth介绍

OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAuth的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAuth是安全的。

  • 简单:不管是OAUTH服务提供者还是应用开发者,都很易于理解与使用
  • 安全:没有涉及到用户密钥等信息,更安全更灵活
  • 开放:任何服务提供商都可以实现OAUTH,任何软件开发商都可以使用OAUTH

OAuth认证授权就三个步骤,三句话可以概括:

  • 获取未授权的Request Token
  • 获取用户授权的Request Token
  • 用授权的Request Token换取Access Token

OAuth的介绍,摘自:http://baike.baidu.com/view/3948029.htm

3. Github登陆

通过Passport实现Github登陆。我们还使用上一篇文章中的环境:Express结合Passport实现登陆认证

  • 申请开发github应用
  • Passport程序实现
  • 运行Github登陆认证

1). 申请开发github应用

2). Passport程序实现

  • 安装Passport的github扩展
  • 增加Github认证策略
  • 定义Github认证的路由配置: 登陆,回调,展示

a. 安装Passport的github扩展

D:\workspace\javascript\nodejs-passport>npm install passport-github

b. 增加Github认证策略

修改app.js

passport.use(new GithubStrategy({//对应从Github申请KEY

clientID: "XXXX",

clientSecret: "XXXX",

callbackURL:
"http://localhost:3000/auth/github/callback"

},function(accessToken, refreshToken, profile, done) {

done(null, profile);

}));

c. 定义Github认证的路由配置: 登陆,回调,展示

  • /auth/github: 通过github,登陆
  • /auth/github/callback: github认证成功后,回调
  • /github: 回调验证后,转向展示示

修改app.js

app.all(‘/github‘, isLoggedIn);

app.get("/github",user.github);

app.get("/auth/github",
passport.authenticate("github",{ scope : "email"}));

app.get("/auth/github/callback",

passport.authenticate("github",{

successRedirect: ‘/github‘,

failureRedirect: ‘/‘

}));

3).运行Github登陆认证

程序日志

D:\workspace\javascript\nodejs-passport>node app.js

Express server listening on port 3000

GET / 200 401ms - 594b

GET /stylesheets/style.css 304 9ms

GET /auth/github 302 8ms - 424b

GET /auth/github/callback?code=7cf818c4590e2aacfe90 302 4052ms - 70b

GET /github 200 4ms - 139b

GET /logout 302 2ms - 58b

GET / 200 3ms - 594b

GET /stylesheets/style.css 304 2ms

4. LinkedIn登陆

  • 申请开发LinkedIn应用
  • Passport程序实现
  • 运行LinkedIn登陆认证

1). 申请开发LinkedIn应用

2). Passport程序实现

  • 安装Passport的LinkedIn扩展
  • 增加LinkedIn认证策略
  • 定义LinkedIn认证的路由配置: 登陆,回调,展示

a. 安装Passport的LinkedIn扩展

D:\workspace\javascript\nodejs-passport>npm install passport-linkedin

b. 增加LinkedIn认证策略

修改app.js

passport.use(new LinkedinStrategy({

consumerKey: "XXXX",

consumerSecret:
"XXXX",

callbackURL:
"http://localhost:3000/auth/linkedin/callback",

userAgent: ‘localhost‘

},function(accessToken, refreshToken, profile, done) {

done(null, profile);

}));

c. 定义LinkedIn认证的路由配置: 登陆,回调,展示

  • /auth/linkedin: 通过LinkedIn,登陆
  • /auth/linkedin/callback: github认证成功后,回调
  • /linkedin: 回调验证后,转向展示示

修改app.js

app.all(‘/github‘, isLoggedIn);

app.get("/github",user.github);

app.all(‘/linkedin‘, isLoggedIn);

app.get("/linkedin",user.linkedin);

app.get("/auth/linkedin",
passport.authenticate("linkedin",{}));

app.get("/auth/linkedin/callback",

passport.authenticate("linkedin",{

successRedirect:
‘/linkedin‘,

failureRedirect: ‘/‘

}));

3).运行LinkedIn登陆认证

程序日志

D:\workspace\javascript\nodejs-passport>node app.js

Express server listening on port 3000

GET / 200 399ms - 638b

GET /stylesheets/style.css 304 4ms

GET /auth/Linkedin 302 3092ms - 256b

GET
/auth/linkedin/callback?oauth_token=75--8f032180-afae-489b-bc3c-3326d80bea6f&oauth_verifier=36091
302 3049ms - 74b

GET /linkedin 200 5ms - 76b

GET /logout 302 1ms - 58b

GET / 200 19ms - 638b

GET /stylesheets/style.css 304 2ms

5. 完整的应用

项目代码我已上传到了github, 项目地址:https://github.com/bsspirit/nodejs-passport

下载及安装

git clone https://github.com/bsspirit/nodejs-passport

npm install

我们非常方便地,实现了Github和LinkedIn登陆认证,是否已经体会到Passport的强大了!把权限这种基础功能,进行合理的封装,是会帮我们节省大量的工作量的

时间: 2024-10-06 02:14:11

Express结合Passport实现登陆认证和Passport现实社交网络OAuth登陆的相关文章

Laravel 5.4建站06--API 认证系统 Passport

介绍 在 Laravel 中,实现基于传统表单的登陆和授权已经非常简单,但是如何满足 API 场景下的授权需求呢?在 API 场景里通常通过令牌来实现用户授权,而非维护请求之间的 Session 状态.现在 Laravel 项目中可以使用 Passport 轻而易举地实现 API 授权过程,通过 Passport 可以在几分钟之内为你的应用程序添加完整的 OAuth2 服务端实现. 安装 使用 Composer 依赖包管理器安装 Passport : composer require larav

laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证

第一部分: 安装passport 使? Composer 依赖包管理器安装 Passport : composer require laravel/passport 接下来,将 Passport 的服务提供者注册到配置?件  config/app.php  的providers  数组中:(5.6后不用加 ) Laravel\Passport\PassportServiceProvider::class utf8 的 varchar 类型字符串最长255,换成utf8mb4最长是191,然而框架

K8S Dashborad登陆认证文档

K8S Dashboard是官方的一个基于WEB的用户界面,专门用来管理K8S集群,并可展示集群的状态.因为我们使用kubeadm搭建的集群会默认开启RABC(角色访问控制机制),所以我们必须要进行额外的设置.关于RABC的概念,网上资料很多,大家务必提前了解.这里简要介绍一下几个重要概念: RBAC K8S 1.6引进,是让用户能够访问 k8S API 资源的授权方式[不授权就没有资格访问K8S的资源] 用户 K8S有两种用户:User和Service Account.其中,User给人用,S

Ubuntu下SSH安装及提高SSH登陆认证速度的办法

Ubuntu 下安装 OpenSSH Server 是无比轻松的一件事情,需要的命令只有一条: sudo apt-get install openssh-server (查看返回的结果,如果没有出错,则用putty.SecureCRT.SSH Secure Shell Client等SSH 客户端软件,输入您服务器的 IP 地址.如果一切正常的话,等一会儿就可以连接上了.并且使用现有的用户名和密码应该就可以登录了.) 然后确认sshserver是否启动了:(或用“netstat -tlp”命令)

spring-security 登陆认证之初次探究

首先,希望还对 spring-security框架完全不懂的新手 下载下Git源码. 引入到项目中.这个短文就是边看源码边聊的.也会启动下项目验证自己的推想. spring-security 登陆认证的配置项如下: <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" default-target-url="/index.ht&qu

Flask中如何实现用户登陆认证?

本文和大家分享的主要是使用Flask实现用户登陆认证的相关知识,希望对大家学习Flask有所帮助. 用户认证的原理 在了解使用Flask来实现用户认证之前,我们首先要明白用户认证的原理.假设现在我们要自己去实现用户认证,需要做哪些事情呢? 1. 首先,用户要能够输入用户名和密码,所以需要网页和表单,用以实现用户输入和提交的过程. 2. 用户提交了用户名和密码,我们就需要比对用户名,密码是否正确,而要想比对,首先我们的系统中就要有存储用户名,密码的地方,大多数后台系统会通过数据库来存储,但是实际上

简单的Python登陆认证小程序

使用Python编写登陆认证小程序.用户连续 3 次输入密码错误即锁定用户. ############# start ############### #!/usr/bin/env python import os import sys # os.system('clear') userfile = file('user_id.txt', 'r+') userlist = [] userdict = {} if os.path.isfile("user_id.txt"): pass el

路飞学城14天集训营作业1—登陆认证

作业一:登陆认证基础需求: 让用户输入用户名密码 认证成功后显示欢迎信息 输错三次后退出程序 升级需求: 可以支持多个用户登录 (提示,通过列表存多个账户信息) 用户3次认证失败后,退出程序,再次启动程序尝试登录时,还是锁定状态(提示:需把用户锁定的状态存到文件里) 初始版本: 1 # -*- coding:utf-8 -*- 2 # author: heimu 3 4 import os 5 6 user_dic = {"heimu_1":"111111",&qu

从 &amp;quot;org.apache.hadoop.security.AccessControlException:Permission denied: user=...&amp;quot; 看Hadoop 的用户登陆认证

假设远程提交任务给Hadoop 可能会遇到?"org.apache.hadoop.security.AccessControlException:Permission denied: user=..." , 当然,假设是spark over YARN, 也相同会遇到相似的问题,比如: ?An error occurred while calling None.org.apache.spark.api.java.JavaSparkContext. : org.apache.hadoop.