Heim > Web-Frontend > js-Tutorial > Hauptteil

Ein Artikel, in dem die Identitätsauthentifizierung von Express in Node ausführlich erläutert wird

青灯夜游
Freigeben: 2023-01-16 19:58:03
nach vorne
2095 Leute haben es durchsucht

Dieser Artikel wird Ihnen helfen, das Express-Framework in Node zu verstehen und die Identitätsauthentifizierung in Express vorzustellen. Ich hoffe, er wird Ihnen hilfreich sein!

Ein Artikel, in dem die Identitätsauthentifizierung von Express in Node ausführlich erläutert wird

Webentwicklungsmodell

Es gibt derzeit zwei gängige Webentwicklungsmodelle:

Traditionelles Webentwicklungsmodell basierend auf serverseitigem Rendering

Das Konzept des serverseitigen Renderings: Der Server sendet an den Client HTML-Seiten werden auf dem Server durch Verkettung von Zeichenfolgen dynamisch generiert. Daher muss der Client keine Technologien wie Ajax verwenden, um zusätzlich Seitendaten anzufordern. [Verwandte Tutorial-Empfehlungen: nodejs-Video-Tutorial, Programmierlehre]

Der Code lautet wie folgt:

app.get('/index.html',(req,res)=>{
  // 1.要渲染的数据
  const user = {name:'zs',age:20}
  // 2.服务器通过字符串的拼接,动态生成 HTML 内容
  const html = `<h1>姓名:${user.name},年龄:${user.age}</h1>`
  // 3.把生成好的页面内容响应给客户端。因此客户端拿到的是带有真实数据的 HTML 页面
  res.send(html)
})
Nach dem Login kopieren

Vor- und Nachteile des serverseitigen Renderns

Vorteile:

1) Das Frontend ist weniger zeitaufwändig : Da die Serverseite für die dynamische Generierung von HTML-Inhalten verantwortlich ist, muss der Browser die Seite nur direkt rendern. Besonders die mobile Version ist stromsparender.

2)Förderlich für SEO: Da der Server auf den gesamten HTML-Seiteninhalt reagiert, ist es für Crawler einfacher, Informationen zu crawlen und abzurufen, was der SEO förderlicher ist.

Nachteile :

1) Beansprucht serverseitige Ressourcen : Das heißt, der Server vervollständigt das Spleißen des HTML-Seiteninhalts. Wenn viele Anfragen vorliegen, führt dies zu einem gewissen Zugriffsdruck Der Server.

2)Die Trennung von Front-End und Back-End ist nicht förderlich und die Entwicklungseffizienz ist gering: Mit serverseitigem Rendering sind Arbeitsteilung und Zusammenarbeit insbesondere bei Projekten nicht möglich mit hoher Front-End-Komplexität, was einer effizienten Projektentwicklung nicht förderlich ist.

Ein neues Webentwicklungsmodell basierend auf Front-End- und Back-End-Trennung

Das Konzept der Front-End- und Back-End-Trennung: Das Front-End- und Back-End-Trennungsentwicklungsmodell basiert auf der weit verbreitete Anwendung der Ajax-Technologie. Kurz gesagt, das Webentwicklungsmodell mit separatem Front-End und Back-End ist ein Entwicklungsmodell, bei dem das Back-End nur für die Bereitstellung von API-Schnittstellen verantwortlich ist und das Front-End Ajax zum Aufrufen der Schnittstelle verwendet.

Vor- und Nachteile der Front-End- und Backend-Trennung

Vorteile:

1) Gute Entwicklungserfahrung. Das Front-End konzentriert sich auf die Entwicklung von UI-Seiten, das Back-End auf die Entwicklung von APIs und das Front-End bietet mehr Optionen

2) Gute Benutzererfahrung. Die weit verbreitete Anwendung der Ajax-Technologie hat die Benutzererfahrung erheblich verbessert und kann problemlos eine teilweise Aktualisierung der Seite realisieren

3) Reduziert den Rendering-Druck auf der Serverseite. Denn die Seite wird letztendlich im Browser jedes Benutzers generiert.

Nachteile:

1) Nicht gut für SE0. Da die vollständige HTML-Seite auf dem Client dynamisch gespleißt werden muss, kann der Crawler die effektiven Informationen der Seite nicht crawlen. (Lösung: Die Verwendung der SSR-Technologie (Server Side Render) von Front-End-Frameworks wie Vue und React kann SEO-Probleme sehr gut lösen!) Hauptfunktionen einer Website auf Unternehmensebene Es handelt sich um eine Anzeige ohne komplexe Interaktion, die eine gute SEO erfordert. Dann müssen wir serverseitiges Rendering und ähnliche Back-End-Verwaltungsprojekte verwenden, die interaktiver sind und keine Berücksichtigung von SEO erfordern. Dann können wir ein Front-End- und Back-End-Trennungsentwicklungsmodell verwenden.

Daher ist das zu verwendende spezifische Entwicklungsmodell nicht absolut, um sowohl die Rendering-Geschwindigkeit der Homepage als auch die Entwicklungseffizienz der Front-End- und Back-End-Trennung zu berücksichtigen. Einige Websites verwenden zunächst ein Entwicklungsmodell -Screen serverseitiges Rendering + andere Seiten mit Front-End- und Back-End-Trennung.

Identitätsauthentifizierung

Identitätsauthentifizierung

(Authentifizierung), auch bekannt als „

Identitätsüberprüfung“, „

Authentifizierung“, bezieht sich auf den Abschluss der Benutzeridentitätsüberprüfung durch bestimmte Mittel bestätigen. Bei der Webentwicklung geht es auch um die Authentifizierung der Benutzeridentität, wie zum Beispiel: Anmeldung mit mobilem Bestätigungscode, Anmeldung per E-Mail-Passwort, QR-Code-Anmeldung usw. für große Websites. Der Zweck der Identitätsauthentifizierung: Bestätigung, dass der Benutzer, der derzeit eine bestimmte Identität beansprucht, tatsächlich der beanspruchte Benutzer ist.

Identitätsauthentifizierung in verschiedenen Entwicklungsmodi

对于服务端渲染前后端分离这两种开发模式来说,分别有着不同的身份认证方案:

1)服务端渲染推荐使用 Session 认证机制

2)前后端分离推荐使用  JWT 认证机制

Session认证机制

HTTP协议的无状态性:指的是客户端的每次HTTP请求都是独立的,连续多个请求之间没有直接的关系,服务器不会主动保留每次HTTP请求的状态。而要想突破HTTP的无状态的限制,就需要借助Cookie。

Cookie是存储在用户浏览器中的一段不超过4KB的字符串。它由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。不同域名下的Cookie 各自独立,每当客户端发起请求时,会自动当前域名下所有未过期的Cookie一同发送到服务器。

Cookie的特性:自动发送、域名独立、过期时限、4KB限制。

Cookie在身份认证中的作用

客户端第一次请求服务器的时候,服务器通过响应头的形式,向客户端发送一个身份认证的Cookie,客户端会自动将Cookie保存在浏览器中。随后,当客户端浏览器每次请求服务器的时候,浏览器会自动将身份认证相关的Cookie,通过请求头的形式发送给服务器,服务器即可验明客户端的身份。

Cookie的安全性问题

由于Cookie是存储在浏览器中的,而且浏览器提供了读写Cookie的API,因此Cookie很容易被伪造,不具有安全性。因此不建议服务器将重要的隐私数据,通过Cookie的形式发送给浏览器,所以千万不要使用Cookie存储重要且隐私的数据,比如用户的身份信息、密码等。

而Session的认证机制就是为了提高cookie安全性的一种认证机制。

Session的工作原理

在Express中使用Session认证

在Express项目中,只需安装 express-session 中间件,即可在项目中使用Session认证:

npm install express-session
Nach dem Login kopieren

express-session中间件安装完成后,需要通过app.use()来注册session中间件,代码如下:

// 配置 Session 中间件
const session = require('express-session')
app.use(session({
  secret:'Session_test', // secret 属性值可以是任意字符串
  resave:false, // 固定写法
  saveUninitialized:true // 固定写法
}))
Nach dem Login kopieren

当express-session中间件配置成功后,即可通过 req.session 来访问和使用 session 对象,从而存储用户的关键信息:

// 登录的API接口
app.post('/api/login',(req,res)=>{
  // 判断用户提交的信息是否正确
  if(req.body.username !=='admin' || req.body.password !=='123456'){
    return res.send({status:1,msg:'登录失败'})
  }
  // 登录成功后,将成功的用户信息保存到session中
  // 注意:只有成功配置了 express-session 这个中间件后,才能通过 req 点出来 session 这个属性
  req.session.user = req.body // 用户的信息
  req.session.islogin = true // 用户的登录状态
  res.send({status:0,msg:'登录成功'})
})
Nach dem Login kopieren

当然也可以直接从 req.session 对象上获取之前存储的数据。代码如下:

app.post('/api/logout',(req,res)=>{
  // 清空session信息
  req.session.destroy()
  res.send({
    status:0,
    msg:'退出登录成功'
  })
})
Nach dem Login kopieren

Session认证的局限性:Session认证机制需要配合Cookie 才能实现。由于Cookie默认不支持跨域访问,所以,当涉及到前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域Session认证。

当前端请求后端接口不存在跨域问题的时候,推荐使用Session身份认证机制。

JWT认证机制

JWT(英文全称:JSON Web Token)是目前最流行的跨域认证解决方案。当前端需要跨域请求后端接口的时候,不推荐使用Session身份认证机制,推荐使用JWT认证机制。

JWT工作原理:用户的信息通过Token字符串的形式,保存在客户端浏览器中。服务器通过还原Token字符串的形式来认证用户的身份。

JWT的组成部分

Header(头部)、Payload(有效荷载)、Signature(签名)。

Payload部分才是真正的用户信息,它是用户信息经过加密之后生成的字符串。

Header和Signature是安全性相关的部分,只是为了保证Token的安全性。

三者之间使用英文的“.”分隔,格式如下:

Header.Payload.Signature
Nach dem Login kopieren

JWT的使用方式: 客户端收到服务器返回的WT之后,通常会将它储存在localStorage或sessionStorage中。此后,客户端每次与服务器通信,都要带上这个WT的字符串,从而进行身份认证。推荐的做法是把JWT放在HTTP请求头的Authorization字段中,格式如下:

Authorization: Bearer <token>
Nach dem Login kopieren

在Express中使用JWT

运行如下命令安装两个JWT相关的包:

# jsonwebtoken用于生成JWT字符串
# express-jwt用于将JWT字符串解析还原成JSON对象
npm install jsonwebtoken express-jwt@5.3.3
Nach dem Login kopieren

定义secret密钥:为了保证JWT字符串的安全性,防止JWT字符串在网络传输过程中被别人破解,我们需要专门定义一个用于加密和解密的secret密钥。

当生成JWT字符串的时候,需要使用 secret 密钥对用户的信息进行加密,最终得到加密好的JWT字符串;当把JWT字符串解析还原成JSON对象的时候,需要使用secret密钥进行解密。

// 定义 secret 密钥,建议将密钥命名为 secretKey
const secretKey = 'Hello Node.js'
Nach dem Login kopieren

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

// 登录接口
app.post('/api/login',(req,res)=>{
  // 将 req.body 请求体中的数据,转存为 userinfo 常量
  const userinfo = req.body
  // 登录失败
  if(userinfo.username !=='admin' || userinfo.password !=='123456'){
    return res.send({
      status:400,
      message:'登录失败!'
    })
  }
  // 三个参数分别是:用户信息对象,加密密钥,配置对象
  const tokenStr = jwt.sign({username: userinfo.username},secretKey,{expiresIn:'20s'})
  // 用户登录成功后,生成 JWT 字符串,通过 token 属性响应给客户端
  res.send({
    status:200,
    message:'登录成功',
    token: tokenStr, // 要发送给客户端的 token 字符串 
  })
})
Nach dem Login kopieren

JWT字符串还原为JSON对象:客户端每次在访问那些有权限接口的时候,都需要主动通过请求头中的Authorization字段将Token字符串发送到服务器进行身份认证。此时,服务器可以通过express-jwt这个中间件,自动将客户端发送过来的Token解析还原成JSON对象。

// 注册将 JWT 字符串解析还原成 JSON 对象的中间件
// expiresJWT({secret:secretKey}) 用来解析 Token 的中间件
// .unless({path:[/^\/api\//]}) 用来指定哪些接口不需要访问权限
app.use(expressJWT({secret:secretKey}).unless({path:[/^\/api\//]}))
Nach dem Login kopieren

使用req.user获取用户信息:当express-jwt这个中间件配置成功之后,即可在那些有权限的接口中,使用req.user对象,来访问从WT字符串中解析出来的用户信息了,示例代码如下:

app.get('/admin/getinfo',function(req,res){
  // 使用 req.user 获取用户信息,并使用data属性将用户信息发送给客户端
  console.log(req.user);
  res.send({
    status:200,
    message:'获取用户信息成功',
    data:req.user, // 要发送给客户端的用户信息
  })
})
Nach dem Login kopieren

捕获解析JWT失败后产生的错误:当使用express-jwt解析Token字符串时,如果客户端发送过来的Token字符串过期或不合法,会产生一个解析失败的错误,影响项目的正常运行。我们可以通过 Express的错误中间件,捕获这个错误并进行相关的处理,示例代码如下:

// 使用全局错误处理中间件,捕获解析 JWT 失败后产生的错误
app.use((err, req, res, next) => {
  // 这次错误是由 token 解析失败导致的
  if (err.name === 'UnauthorizedError') {
    return res.send({
      status: 401,
      message: '无效的token',
    })
  }
  res.send({
    status: 500,
    message: '未知的错误',
  })
})
Nach dem Login kopieren

具体详细代码如下:

// 导入 express 模块
const express = require('express')
// 创建服务器
const app = express()

// 导入JWT相关的两个包
const jwt = require('jsonwebtoken')
const expressJWT = require('express-jwt')

// 允许跨域资源共享
const cors = require('cors')
app.use(cors())

// 解析 post 表单数据的中间件
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({ extended: false }))

// 定义 secret 密钥,建议将密钥命名为 secretKey
const secretKey = 'Hello Node.js'

// 注册将 JWT 字符串解析还原成 JSON 对象的中间件
// expiresJWT({secret:secretKey}) 用来解析 Token 的中间件
// .unless({path:[/^\/api\//]}) 用来指定哪些接口不需要访问权限
app.use(expressJWT({secret:secretKey}).unless({path:[/^\/api\//]}))

// 登录接口
app.post('/api/login',(req,res)=>{
  // 将 req.body 请求体中的数据,转存为 userinfo 常量
  const userinfo = req.body
  // 登录失败
  if(userinfo.username !=='admin' || userinfo.password !=='123456'){
    return res.send({
      status:400,
      message:'登录失败!'
    })
  }
  // 三个参数分别是:用户信息对象,加密密钥,配置对象
  const tokenStr = jwt.sign({username: userinfo.username},secretKey,{expiresIn:'50s'})
  // 用户登录成功后,生成 JWT 字符串,通过 token 属性响应给客户端
  res.send({
    status:200,
    message:'登录成功',
    token: tokenStr, // 要发送给客户端的 token 字符串 
  })
})

// 这是一个有权限的API接口
app.get('/admin/getinfo',function(req,res){
  // 使用 req.user 获取用户信息,并使用data属性将用户信息发送给客户端
  console.log(req.user);
  res.send({
    status:200,
    message:'获取用户信息成功',
    data:req.user, // 要发送给客户端的用户信息
  })
})

// 使用全局错误处理中间件,捕获解析 JWT 失败后产生的错误
app.use((err, req, res, next) => {
  // 这次错误是由 token 解析失败导致的
  if (err.name === 'UnauthorizedError') {
    return res.send({
      status: 401,
      message: '无效的token',
    })
  }
  res.send({
    status: 500,
    message: '未知的错误',
  })
})

// 调用app.listen 方法,指定端口号并启动web服务器
app.listen(80,function(){
  console.log('Express server running at http://127.0.0.1:80');
})
Nach dem Login kopieren

更多node相关知识,请访问:nodejs 教程

Das obige ist der detaillierte Inhalt vonEin Artikel, in dem die Identitätsauthentifizierung von Express in Node ausführlich erläutert wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!