介绍
session是服务器,为每个用户的浏览器创建的一个会话对象,这个session 会记录到浏览器的cookie,用来区分用户
我们使用的是nestjs,默认框架express它也支持express的插件,所以我们就可以安装express的session
npm i express-session --save
需要智能提示可以装一个声明依赖
npm i @types/express-session -D
然后在main.ts引入,通过app.use注册session
import * as session from 'express-session'
app.use(session())
参数配置详解
secret | 生成服务端session签名,可以理解为加盐 |
name | 生成客户端cookie的名字,默认connect.sid |
cookie | 设置返回到前端 key的属性,默认值为{ path: ‘/’, httpOnly: true, secure: false, maxAge: null }。 |
rolling | 在每次请求时强行设置 cookie,这将重置 cookie 过期时间(默认:false) |
nestjs配置
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { VersioningType } from '@nestjs/common';
import * as session from 'express-session'
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(session({ secret: 'zl', name: 'zl.session', cookie: { maxAge: null }, rolling: true }))
app.enableVersioning({
type: VersioningType.URI
})
await app.listen(3000);
}
bootstrap();
验证码案例
前端页面实现
前端react ts antd fetch
注意,为啥codeUrl是一个接口地址,而不是图片地址,直接赋值给了img的src属性
原因是初始化加载页面的时候codeUrl作为接口地址会直接访问服务端的code接口,服务端然后发送给前端所需要的数据,比如图片格式,以及把data(就是验证码图片)发送给前端进行了渲染,后面点击图片更换验证码也是访问的code接口
import React, { useState } from 'react';
import { Button, Form, Input, Row, Col } from 'antd';
import './App.css'
type FieldType = {
username?: string;
password?: string;
remember?: string;
};
const App: React.FC = () => {
const [codeUrl, setCodeUrl] = useState('/api/user/code')
const onClick = () => {
setCodeUrl(codeUrl + "?" + Math.random())
}
const onFinish = async (values: any) => {
console.log(values);
await fetch('/api/user/create', {
method: 'POST',
body: JSON.stringify(values),
headers: {
'content-type': 'application/json'
}
}).then((res) => {
return res.json()
})
};
return (
<div className='main'>
<Form
name="basic"
labelCol={{ span: 8 }}
wrapperCol={{ span: 16 }}
style={{ width: 600 }}
initialValues={{ remember: true }}
autoComplete="off"
onFinish={onFinish}
>
<Form.Item<FieldType>
label="用户名"
name="username"
>
<Input />
</Form.Item>
<Form.Item<FieldType>
label="密码"
name="password"
>
<Input.Password />
</Form.Item>
<Form.Item
label="验证码"
name="yzm"
>
<div style={{ display: 'flex' }}>
<Input />
<img src={codeUrl} onClick={onClick}></img>
</div>
</Form.Item>
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</div>
)
};
export default App;
设置请求头
headers: {
'content-type': 'application/json'
}
跨域问题解决
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:3000', //目标url
changeOrigin: true, //支持跨域
rewrite: (path) => path.replace(/^\/api/, ""),
//重写路径,替换/api
}
}
}
})
服务端接口实现
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as session from 'express-session'
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(session({ secret: "zl", name: "zl.sid", rolling: true, cookie: { maxAge: null } }))
await app.listen(3000);
}
bootstrap();
安装验证码插件svgCaptcha
npm install svg-captcha -S
user.controller
import { Controller, Get, Post, Body, Param, Request, Query, Headers, HttpCode, Res, Req, Session } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import * as svgCaptcha from 'svg-captcha';
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) { }
@Get('code')
createCaptcha(@Req() req, @Res() res,@Session() session) {
const captcha = svgCaptcha.create({
size: 4,//生成几个验证码
fontSize: 50, //文字大小
width: 100, //宽度
height: 34, //高度
background: '#cc9966', //背景颜色
})
session.code = captcha.text //存储验证码记录到session
res.type('image/svg+xml')
res.send(captcha.data) // 返回给客户端的数据,就是验证码图片
}
@Post('create')
createUser(@Body() body,@Session() session) {
console.log(body,session?.code);
if(body?.yzm && session?.code && body.yzm===session.code){
console.log(11);
return {
message: "验证码正确"
}
} else {
return {
message: "验证码错误"
}
}
}
}
请求code接口时,Cookies就存储了验证码,为后面验证验证码是否正确做了铺垫
请求接口时如果接口里面有参数,得要用到里面得参数,不用就删除,否则有参数却不使用,会造成接口访问不到得情况,这里面的三个参数都是使用了的,如果不使用就删除不必要的参数