Node.js——前后端的身份认证

249 阅读3分钟

一.web开发模式

1.基于基于服务器端渲染的传统web开发模式

服务端渲染概念:服务器发送给客户端的HTML页面,是在服务器通过拼接字符串,动态生成的。

优点:

  • 前端耗时少。

  • 有利于SEO。

缺点:

  • 占用服务器端资源。

  • 不利于前后端分离,开发效率低。

2.基于前后端分离的web开发模式

前后端分离概念:前后端分离的开发模式,依赖于Ajax技术的广泛应用。简而言之,就是后端只负责提供API接口,前端使用Ajax调用接口的开发模式。

优点:

  • 开发体验好。

  • 用户体验好。

  • 减轻了服务器端的渲染压力。

缺点:

不利于SEO。

3.如何进行选择

主要展示而没有复杂交互,且需要良好SEO,这时就可选择服务器端渲染。

交互性较强,需后台管理项目,不需要考虑SEO,这时就可选择前后端分离。

注:具体使用何种开发模式并不是绝对的,这两种根据具体情况也可以两者兼用。

二.身份认证

身份认证又称"身份验证"、"鉴权",是指通过一定手段,完成对用户身份的确认。

不同模式下的身份认证:

  • 服务器端渲染——————Session认证机制。

  • 前后端分离——————JWT认证机制。

三.Session认证机制

1.HTTP协议的无状态性

指的是客户端的每次HTTP请求都是独立的,连续多个请求之间没有直接的关系,服务器不会主动保留每次HTTP请求的状态。

2.Cookie

它是存储在用户浏览器中的一段不超过4KB的字符串。它由一个名称(Name),一个值(Value)和其它几个用于控制Cookie有效期,安全性,使用范围的可选属性组成的。

注:不同域名下Cookie各自独立,每当客户端发起请求时,会自动把当前域名下所有未过期的Cookie一同发送到服务器。

特性:

  • 自动发送。

  • 域名独立。

  • 过期时限。

  • 4KB限制。

注:Cookie不具有安全性,易被伪造,不要在其中存储重要数据。

3.在Express中使用Session认证

安装:

npm i express-session

导入:

const session = require('express-session');

用app.use()来注册session中间件:

app.use(session({
    secret:''  //可以为任意字符串
    reave:false  //固定写法
    saveUninitialized:true //固定写法
}))

配置成功后可以req.session来访问和使用session对象。

在session中存数据:

app.post('/api/login',(req,res)=>{
   if(req.body.username !== 'admin' || req.body.password !== '000000'){
       return res.send({status:1,msg:'登录失败!'});
   }
   req.session.user = req.body;//将用户信息存储到Session中
   req.session.islogin = true;//将用户的登录状态存储到Session中
   res.send({status:0,msg:'登录成功'});
})

在session中取数据:

app.get('/api/username',(req,res)=>{
    if(!req.session.islogin){
        return res.send({status:1,msg:'fail'});
    }
    res.send({status:0,msg:'success',username:req.session.user,username})
})

清空session:

//调用req.session.destroy()即可
app.post('/api/logout',(req,res)=>{
    req.session.destroy();
    res.send({status:0,msg:'退出登录成功'});
})

四.JWT认证机制

目前最流行的跨域认证解决方案。

注:前端请求,后端接口不存在跨域问题,推荐使用Session。

1.组成部分

Header.Payload.Signature

Header:头部。(保证安全性)

Payload:有效荷载。(真正的用户信息)

Signature:签名。(保证安全性)

2.使用方式

返回的JWT通常在储存在localStorage或sessionStorage中。

方法:把JWT放在HTTP请求头的Authorization字段中。

Authorization:Bearer < token >

3.在Express中使用JWT

安装:

npm i jsonwebtoken express-jwt

导入:

const jwt = require('jsonwebtoken');
const expressJWT = =require('express-jwt')

定义密钥:

const secretkey = 'itheima No1';

调用jsonwebtoken包提供的sign()方法,将用户信息加密成token字符串,响应给客户端。

app.post('/api/login',(req,res)=>{
    res.send({status:0,
    msg:'登录成功'token:jwt.sign({username:userinfo.username},secretkey,{expiresIn:'30s'})
    })
})

将JWT字符串还原为JSON对象:

app.use(expressJWT({secret:secretkey}),.unless({path:[/^\/api\//]}))

使用req.user获取用户信息:

app.use('/admin/getinfo',(req,res)=>{
    res.send({
        status:200,
        msg:'获取用户信息成功!',
        data:req.user
    })
})

捕获解析JWT失败后产生的错误:

app.use((err,req,res,next)=>{
    if(err.name === 'UnauthorizedError'){
        return res.send({status:401,msg:'无效的token'});
    }
    res.send({status:500,msg:'未知错误'})
})