打开 src/auth 下面的 auth.middleware.ts 文件,在这个文件里可以定义一个新的中间件,先在文件的顶部导入点东西,导入 jwt,来自 jsonwebtoken 这个包。
这里可以再调整一下这个导入的顺序,一般可以把 Node.js 自带的模块或者额外安装的模块导入放在自己定义的模块导入的上面。
再从应用的配置里,导入 PUBLIC_KEY,来自上一级目录里的 app 下面的 app.config。
下面再找个地方定义验证用户身份的中间件。 export 一个函数,名字叫 authGuard ,用箭头函数的写法定义它。这个函数有几个参数,一个是 request,类型是 Request,还有 response,类型是 Response,还有一个 next,类型是 NextFunction。
在函数的主体里面,先在控制台输出一行提示文字,验证用户身份。 接着再用一组 try,catch,把要做的事情放在 try 区块里,可以从请求头部里面把 Authorization 提取出来。 添加一个 authorization ,它的值可以用一下 request.header 这个方法,需要的头部是 Authorization。
下面可以判断一下,如果从请求头部里没找到 Authorization,也就是在客户端发送请求的时候没有加这个头部数据,我们可以直接 throw 一个异常。这样就会到 catch 区块里面去处理。
然后再提取 JWT 令牌的值。添加一个 token,它的值可以用一下 authorization 这个字符串上的 replace 方法,用它替换字符串里的字符,要替换掉的是 Bearer 空格,替换成一个空白,意思就是去掉字符串里的 Bearer 空格。剩下的东西就是我们需要的令牌了。
做一下判断,如果没找到 token 的值,就 throw 一个异常。
有了令牌就可以验证一下这个令牌真实有效性了,用一下 jwt 上面提供的 verify() 方法,把令牌交给这个方法,作为它的第一个参数。验证令牌的时候需要用到公钥,这里就是 PUBLIC_KEY,提供一个选项参数,说明一下令牌的加密算法,algorithms ,算法是 RS256 。
验证之后,继续下一步,执行 next()。
在这个 catch() 区块里面,执行一下 next() 带着一个错误,设置一下错误信息,UNAUTHORIZED 表示未授权。
如果请求里没有 Authorization 头部,没找到令牌,或者令牌无效,都会在 catch 这里处理,这里就是把异常情况再转交给应用默认的异常处理器去处理。
打开 app/app.middleware.ts 找到在这里定义的 defaultErrorHandler,在 switch 里面添加一种新的情况,如果错误信息是 UNAUTHORIZED ,可以把响应的状态码设置成 401,响应的信息设置成 请先登录。