NestJS学习笔记之session

介绍

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就存储了验证码,为后面验证验证码是否正确做了铺垫

请求接口时如果接口里面有参数,得要用到里面得参数,不用就删除,否则有参数却不使用,会造成接口访问不到得情况,这里面的三个参数都是使用了的,如果不使用就删除不必要的参数

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值