修改用户的实体类 userEntity
import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
BeforeInsert
} from "typeorm"
import NodeAuth from "node-auth0"
import { Exclude, Expose } from "class-transformer"
import * as jwt from "jsonwebtoken"
@Entity ( { name: "user" } )
export class UserEntity {
@Exclude ( )
private nodeAuth: NodeAuth
constructor ( ) {
this . nodeAuth = new NodeAuth ( )
}
@Expose ( )
private get token ( ) {
const { username, id } = this
return jwt. sign (
{ id, username } ,
process. env. SECRET ,
{ expiresIn: "7d" }
)
}
public toResponseObject ( isShowToken = true ) : { [ key: string ] : any } {
const { nodeAuth, password, token, username, ... params } = this
const responseData = {
username,
... params
}
if ( isShowToken) {
return Object. assign ( responseData, { token } )
} else {
return responseData
}
}
@PrimaryGeneratedColumn ( {
type : "int" ,
name: "id" ,
comment: "主键id"
} )
id: number
@Column ( {
type : "varchar" ,
nullable: true ,
length: 50 ,
unique: true ,
name: "username" ,
comment: "用户名"
} )
username: string
@Column ( {
type : "varchar" ,
nullable: false ,
length: 20 ,
default : "123456" ,
name: "password" ,
comment: "密码"
} )
password: string
@Column ( {
type : 'varchar' ,
nullable: true ,
length: 50 ,
name: 'email' ,
comment: "邮箱"
} )
email: string ;
@Column ( {
type : 'varchar' ,
nullable: true ,
length: 11 ,
name: 'mobile' ,
comment: "手机号"
} )
mobile: string ;
@Column ( 'tinyint' , {
nullable: true ,
default : ( ) => 0 ,
name: 'is_del' ,
comment: '是否删除,1表示删除,0表示正常'
} )
isDel: number ;
@CreateDateColumn ( {
type : 'timestamp' ,
nullable: true ,
name: 'created_at' ,
comment: '创建时间'
} )
createdAt: Date;
@UpdateDateColumn ( {
type : 'timestamp' ,
nullable: true ,
name: 'updated_at' ,
comment: '更新时间' ,
} )
updateAt: Date;
@BeforeInsert ( )
makePassword ( ) : void {
this . password = this . nodeAuth. makePassword ( this . password) ;
}
}
登录的时候校验用户名和密码及返回token LoginService
import { Injectable } from "@nestjs/common"
import { Respository, getManager, EntityManager } from "typeorm"
import { UserEntity } from "../user.entity"
import NodeAuth from "node-auth0"
import { jwt } from "../../../utils/jwt"
import { RedisUtilsService } from "../../redis-utils/redis-utils.service"
type CommonType = { [ key: string ] : any }
@Injectable ( )
export class LoginService {
private nodeAuth: NodeAuth
constructor (
private redisUtilsService: RedisUtilsService
) {
this . nodeAuth = new NodeAuth ( )
}
async login ( data: CommonType) : Promise< any | string > {
const { username, password } = data
return getManager ( )
. transaction ( async ( manager: EntityManager) => {
const user = await manager. findOne ( UserEntity, { username } )
if (
user &&
this . nodeAuth. checkPassword ( password, user, password)
) {
const token = jwt. createToken ( String ( user. id) )
const redisData = {
token,
user
}
this . redisUtilsService. set ( String ( user. id) , redisData)
return { ... user, token }
} else {
return "账号或密码错误"
}
} )
. then ( res => {
} )
. catch ( err => {
console . log ( err)
} )
}
}
import {
Injectable,
canActivate,
Logger,
HttpException,
HttpStatus,
ExecutionContext
} from "@nestjs/common"
import { Observable } from "rxjs"
import { jwt } from "../utils/jwt"
import * as url from "url"
import { RedisUtilsService } from "../modules/redis-utils/redis-utils.service"
@Injectable ( )
export class AuthGuard implements canActivate {
constructor (
private redisUtilsService: RedisUtilsService
) { }
async canActivate (
context: ExecutionContext
) : Promise< boolean > {
const request = context. switchToHttp ( ) . getRequest ( )
const token =
context. switchToRpc ( ) . getData ( ) . headers. token ||
context. switchToHttp ( ) . getData ( ) . body. token ||
this . getUrlQuery ( request. url, "token" )
Logger. log ( `当前的token: ${ token} ` , "AuthGuard" )
if ( token) {
const currentUserId = jwt. decodeToken ( token)
const redisData = await this . redisUtilsService. get ( currentUserId)
console . log ( JSON . stringify ( redisData, "redis数据" ) )
if ( Object. is ( token, redisData. token) ) {
request. user = redisData. token
return true
} else {
throw new HttpException ( "token已经失效,请重新登录" , HttpStatus. UNAUTHORIZED )
}
} else {
throw new HttpException ( "你还没有登录,请先登录" , HttpStatus. UNAUTHORIZED )
}
}
private getUrlQuery ( urlPath: string , key? : string ) : string | { [ key: string ] : any } {
const query = url. parse ( urlPath, true ) . query
if ( key) {
return query[ key]
} else {
return query
}
}
}
使用redis做单点登录 redisUtilsModue 在app中引入 全局使用
import { Module, Global } from '@nestjs/common' ;
import { RedisModule } from 'nestjs-redis'
import { RedisUtilsService } from './redis-utils.service' ;
@Global ( )
@Module ( {
imports: [
RedisModule. register ( {
port: 6379 ,
host: '127.0.0.1' ,
password: '' ,
db: 0
} )
] ,
providers: [
RedisUtilsService,
] ,
exports: [
RedisUtilsService,
]
} )
export class RedisUtilsModule { }
import { Injectable } from "@nestjs/common"
import { RedisService } from "nestjs-redis"
import { Redis } from "ioredis"
@Injectable ( )
export class RedisUtilsService {
public client: Redis
constructor (
private redisService: RedisService
) { }
onModuleInit ( ) : void {
this . getClient ( )
}
public getClient ( ) : void {
this . client = this . redisService. getClient ( )
}
public async set ( key: string , value: { [ key: string ] : any } | string , second? : number ) : Promise< void > {
value = JSON . stringify ( value)
if ( ! second) {
await this . client. setex ( key, 24 * 60 * 60 , value)
} else {
await this . client. set ( key, value, "EX" , second)
}
}
public async get ( key: string ) : Promise< any > {
const data = await this . client. get ( key)
if ( data) {
return JSON . parse ( data)
} else {
return null
}
}
public async del ( key: string ) : Promise< any > {
await this . client. del ( key)
}
public async flushall ( ) : Promise< any > {
await this . client. flushall ( )
}
}
import NodeSSO from "node-sso"
class JWT {
private nodeSSO: NodeSSO
constructor ( secret: string ) {
this . nodeSSO = new NodeSSO ( secret)
}
public createToken ( user: string | { [ key: string ] : any } ) : string {
return this . nodeSSO. generateToken ( user)
}
public decodeToken ( token: string ) : string | null {
return this . nodeSSO. decryptToken ( token)
}
}
export const jwt = new JWT ( process. env. SECRET )