前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Nest教程】Nest项目集成JWT接口认证

【Nest教程】Nest项目集成JWT接口认证

作者头像
青年码农
发布于 2021-02-03 03:14:56
发布于 2021-02-03 03:14:56
3K70
代码可运行
举报
文章被收录于专栏:青年码农青年码农
运行总次数:0
代码可运行

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

我们都知道,http协议本身是无状态的协议,如果在一个系统中,我们只有登录后在可以操作,由于http是无状态的,所以那就必须每个接口都需要一个认证,来查看当前用户是否有权限。今天我们就基于之前的项目,集成JWT。

1 user.service方法

增加一个查询单个用户的方法,这个方法不需要对应控制器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
async findOne(name: string): Promise<any | undefined> {
  const user = await this.UserRepository.findOne({
    where: {
      name: name,
    },
  });
  if (user == undefined) {
    return void 0;
  } else {
    return user;
  }
}

2 增加登录路由

在user.controller文件中新增路由,里面的逻辑暂时什么都不写

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 @Post('/login')
  async login(@Body() loginParmas: any) {}

3 安装依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 yarn add passport passport-jwt passport-local @nestjs/passport @nestjs/jwt -S

4 创建Auth模块

src下新建文件夹logical/auth,auth目录下为我们逻辑功能。

constants.ts - 常量

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export const jwtConstants = {
  secret: 'NestAPI',
};

jwt.strategy.ts - 验证策略

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  // JWT验证 - Step 4: 被守卫调用
  async validate(payload: any) {
    return {
      id: payload.id,
      name: payload.name,
      nickname: payload.nickname,
    };
  }
}

auth.service.ts - 验证逻辑

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { Injectable, Inject } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { UserService } from '../../user/user.service';
import { encryptPassword } from '../../utils/cryptogram';

@Injectable()
export class AuthService {
  constructor(
    @Inject('UserService') private readonly usersService: UserService,
    private readonly jwtService: JwtService,
  ) {}

  // JWT验证 - Step 2: 校验用户信息
  async validateUser(name: string, password: string): Promise<any> {
    const user = await this.usersService.findOne(name);
    if (user) {
      const hashedPassword = user.password;
      const salt = user.passwdSalt;
      // 通过密码盐,加密传参,再与数据库里的比较,判断是否相等
      const hashPassword = encryptPassword(password, salt);
      if (hashedPassword === hashPassword) {
        // 密码正确
        return {
          code: 1,
          user,
        };
      } else {
        // 密码错误
        return {
          code: 2,
          user: null,
        };
      }
    }
    // 查无此人
    return {
      code: 3,
      user: null,
    };
  }

  // JWT验证 - Step 3: 处理 jwt 签证
  async certificate(user: any) {
    const payload = {
      id: user.id,
      name: user.name,
      nickname: user.nickname,
    };
    try {
      const token = this.jwtService.sign(payload);
      return {
        code: 200,
        data: {
          token,
        },
        msg: `登录成功`,
      };
    } catch (error) {
      return {
        code: 600,
        msg: `账号或密码错误`,
      };
    }
  }
}

auth.module.ts

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { UserModule } from '../../user/user.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '8h' }, // token 过期时效
    }),
    UserModule,
  ],
  providers: [AuthService, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}

上面这些属于配置,调用我们需要在路由/login里面写逻辑,第2步中我们只定义了一个空的方法,我们接下来写逻辑

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { ApiTags, ApiParam, ApiQuery, ApiHeader } from '@nestjs/swagger';
import {
  Controller,
  Post,
  Body,
  Logger,
  HttpCode,
  UseGuards,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from '../logical/auth/auth.service';
import { UserService } from './user.service';

@ApiTags('用户管理')
@Controller('user')
export class UserController {
  constructor(
    private readonly authService: AuthService,
    private readonly userService: UserService,
  ) {}

  /**
   * 用户登录
   */
  @Post('/login')
  async login(@Body() loginParmas: any) {
    const authResult = await this.authService.validateUser(
      loginParmas.name,
      loginParmas.password,
    );
    switch (authResult.code) {
      case 1:
        return this.authService.certificate(authResult.user);
      case 2:
        return {
          code: 600,
          msg: `账号或密码不正确`,
        };
      default:
        return {
          code: 600,
          msg: `当前用户未查到`,
        };
    }
  }
}

5 测试

运行项目,我们用postman测试

登录成功,返回token。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 青年码农 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
7 条评论
热度
最新
现在部署 spark 2.1.0也报java.lang.NoSuchMethodError: org.apache.hadoop.hive.ql.session.SessionState.reloadAuxJars()V
现在部署 spark 2.1.0也报java.lang.NoSuchMethodError: org.apache.hadoop.hive.ql.session.SessionState.reloadAuxJars()V
回复回复点赞举报
博文后面的报错问题后面有解决方案吗
博文后面的报错问题后面有解决方案吗
回复回复点赞举报
发现必须拷贝hive-site.xml到spark的conf目录下,否则读不到现有的hive元数据信息
发现必须拷贝hive-site.xml到spark的conf目录下,否则读不到现有的hive元数据信息
回复回复点赞举报
请问一下楼主,这是什么情况呢?
请问一下楼主,这是什么情况呢?
回复回复点赞举报
beeline里面的日志
beeline里面的日志
回复回复点赞举报
Unknown HS2 problem when communicating with Thrift server.Error: Could not open client transport with JDBC Uri: jdbc:hive2://cdh0:10088/;principal=hive/cdh0@HERALEIGN.COM: Peer indicated failure: Unsupported mechanism type GSSAPI (state=08S01,code=0)
Unknown HS2 problem when communicating with Thrift server.Error: Could not open client transport with JDBC Uri: jdbc:hive2://cdh0:10088/;principal=hive/cdh0@HERALEIGN.COM: Peer indicated failure: Unsupported mechanism type GSSAPI (state=08S01,code=0)
回复回复点赞举报
thrift日志:java.lang.RuntimeException: org.apache.thrift.transport.TTransportException: Unsupported mechanism type GSSAPI
thrift日志:java.lang.RuntimeException: org.apache.thrift.transport.TTransportException: Unsupported mechanism type GSSAPI
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
十月杂题选做
剩余的树上每个点都必须经过。因此除了起点与终点之间路径上的边会被经过恰好一次以外,其余所有边都会被经过恰好两次。
yzxoi
2022/10/31
4480
十月杂题选做
NOIP2022模拟赛二 By YJC 10.20
其中 siz_{x,c} 代表从点 x 出发,不经过颜色 c 的点,所构成的连通块大小。
yzxoi
2022/10/31
2710
Public NOIP Round
DP, 二分, 二分图, 决策单调性, 剪枝, 爆搜, 线段树, 线段树优化 DP, 背包, 贪心
yzxoi
2022/10/31
5680
CSP-S2022模拟赛1 10.04
注意到答案一定很小,设 表示左端点为 ,能合并出数字 的右端点。
yzxoi
2022/10/28
2900
义乌中学暑假集训 2021.07.09 D
给定一个长度为 n 的序列 a_i,有 m 个询问,每次询问给定 l,r,求对于 i,j\in[l,r],且满足 i\not = j,a_i - a_j 的最小值。
yzxoi
2022/09/19
3780
临时抱佛脚
\(f[i][j] = min(f[i][k], f[k + 1][j])\)的dp方程,猜想其满足四边形不等式
attack
2019/04/09
7310
YbtOJ 774「分块算法」奇妙的树
假设 i 号点的父节点为 f_i(方便起见认为 f_1=0),小 A 发现这棵树非常奇妙,它满足一个特殊的性质:对于任意整数 i\in[2,n],满足 f_{i-1}\le f_i < i
yzxoi
2022/09/19
4400
YbtOJ 644「平衡树」模糊序列
小 A 有一个长度为 n 的正整数序列 a_{1\sim n},但其中所有的值都已经模糊不清了,只知道每个数的取值范围。
yzxoi
2022/09/19
2550
[Atcoder][CF]简单题选做练习笔记 2
第一个式子,要求 p_i \equiv 0 \pmod 3,第二个式子要求 p_i \equiv 1 \pmod 3 且 p_j \equiv 2 \pmod 3 或者反过来。
Clouder0
2022/09/23
3830
CF1748E Yet Another Array Counting Problem
对于长度为 n 的序列 x,定义其在子段 [l;r] 的“最左端最大值位置”为最小的满足 l\leq i\leq r 且 x_i=\max_{j=l}^rx_j 的整数 i。给定整数 n,m 和长度为 n 的序列 a,你需要求出满足下列要求的序列 b 的数量:
yzxoi
2022/11/21
2740
YbtOJ 794「cdq 分治 整体二分」奇度边集
每加入一条边之后,小 A 都要先判断是否存在一个边集使得所有点度数都是奇数,若存在则求出所有符合要求的边集中 最大边权 的 最小值,若不存在则输出 -1。
yzxoi
2022/09/19
2540
NOIP2022模拟赛二 By YJC 10.20
其中 siz_{x,c} 代表从点 x 出发,不经过颜色 c 的点,所构成的连通块大小。
yzxoi
2024/02/02
1890
Public NOIP Round
很容易设出一个简单的 DP,设 f_{i} 表示当前子序列结尾为 a_i,且保证最终一定含 a_i,长度最大值。
yzxoi
2024/02/02
1800
CSP-S2022模拟赛1 10.04
剩余的树上每个点都必须经过。因此除了起点与终点之间路径上的边会被经过恰好一次以外,其余所有边都会被经过恰好两次。
yzxoi
2024/02/02
1870
YbtOJ 735「动态树」毒瘤染色
接下来小 A 会进行 q 次操作,每次操作给出两个正整数 x,y,要求判断往 G 中加入 (x,y) 后该图是否仍然是毒瘤图,若是则加入这条边,否则不加入。
yzxoi
2022/09/19
4830
CF1129D Isolation
给定一个长度为 n 的序列 a_{1\sim n},把它分割成若干段,使得每段出现过恰好一次的元素个数 \leq k,求方案数对 998244353 取模的结果。
yzxoi
2022/09/19
8570
2017.10.23解题报告
预计分数:100+60+0=160 实际分数:100+80+0=180 T1 题目描述 现在有一个字符串,每个字母出现的次数均为偶数。接下来我们把第一次出现的字母a和第二次出现的a连一条线,第三次出现的和四次出现的字母a连一条线,第五次出现的和六次出现的字母a连一条线...对其他25个字母也做同样的操作。 现在我们想知道有多少对连线交叉。交叉的定义为一个连线的端点在另外一个连线的内部,另外一个端点在外部。 下图是一个例子,共有三对连线交叉(我们连线的时候,只能从字符串上方经过)。 输入格式 一行一个字符串。
attack
2018/04/11
8380
bzoj 3091 & Luogu P4842 城市旅行 题解
对于 100\% 的数据,满足 1<=N<=50,000;1<=M<=50,000;1<=a_i<=10^6;1<=D<=100;1<=U,V<=N
yzxoi
2022/09/19
2840
YbtOJ 976「母函数」随机减法
小 A 有一个长度为 n 的序列 a 和一个初始值为 0 的计数器 cnt,他想要对其进行 k 次操作。
yzxoi
2022/09/19
2.1K0
YbtOJ 976「母函数」随机减法
基于连通性状态压缩的动态规划问题
基于连通性状态压缩的动态规划问题 基于状态压缩的动态规划问题是一类以集合信息为状态且状态总数为指数级的特殊的动态规划问题.在状态压缩的基础上,有一类问题的状态中必须要记录若干个元素的连通情况,我们称这样的问题为基于连通性状态压缩的动态规划问题,本文着重对这类问题的解法及优化进行探讨和研究. 本文主要从动态规划的几个步骤——划分阶段,确立状态,状态转移以及程序实现来介绍这类问题的一般解法,会特别针对到目前为止信息学竞赛中涌现出来的几类题型的解法作一个探讨.结合例题,本文还会介绍作者在减少状态总数和降低转移开销
Angel_Kitty
2018/04/10
1K0
基于连通性状态压缩的动态规划问题
相关推荐
十月杂题选做
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档