当前位置: 首页 > news >正文

【图文并茂】ant design pro 如何对接登录接口

在这里插入图片描述
在这里插入图片描述
我们拥有 12 年建站编程经验

  1. 虚拟产品交易平台定制开发
  2. ant design pro & nodejs 多角色权限管理系统源码
  3. WordPress 外贸电商独立站建站

我的网站

ant design pro 如何去对接登录呢。

首先你后端要有登录接口。

例如我的:

const login = handleAsync(async (req: Request, res: Response) => {const { email, password } = req.body;const user = await User.findOne({ $or: [{ email }, { name: email }] });if (!user) {res.status(400);throw new Error('User not found');}if (!user.live) {res.status(401);throw new Error('User is not live');}if (await bcrypt.compare(password, user.password)) {const refreshToken = generateRefreshToken(user._id);res.json({success: true,name: user.name || user.email,token: generateToken(user.id),refreshToken,});} else {res.status(401);throw new Error('Invalid email or password');}
});

登录接口比较简单的,无外乎查下数据库,匹配下用户名和密码,找到这条用户

主要是返回的信息,我这里要返回的是 token ,这个信息给到前端,

前端要拿到这个 token。

我这里用的是 json web token , 其实就相当于一个人的身份证一样,有了身份证就能进入系统。

只是这种身份证并不是固定的,每次都可以生成别的,也可能有时间限制,反正能代表一个人就是了。

如何生成 token 呢:

参考下我的

import jwt from 'jsonwebtoken';const generateToken = (id: string): string => {return jwt.sign({ id }, process.env.JWT_SECRET as string, {expiresIn: process.env.JWT_EXPIRE,});
};const generateRefreshToken = (id: string): string => {return jwt.sign({ id }, process.env.REFRESH_JWT_SECRET as string, {expiresIn: process.env.REFRESH_JWT_EXPIRE,});
};export { generateToken, generateRefreshToken };

前端实现

前端比较简单了,总体代码是这样的:

src/pages/User/Login/index.tsx

import { useIntl } from '@umijs/max';
import { Footer } from '@/components';
import { login } from '@/services/ant-design-pro/api';
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { LoginForm, ProFormText } from '@ant-design/pro-components';
import { FormattedMessage, history, SelectLang, useModel, Helmet } from '@umijs/max';
import { message } from 'antd';
import Settings from '../../../../config/defaultSettings';
import React from 'react';
import { flushSync } from 'react-dom';
import { createStyles } from 'antd-style';const useStyles = createStyles(({ token }) => {return {action: {marginLeft: '8px',color: 'rgba(0, 0, 0, 0.2)',fontSize: '24px',verticalAlign: 'middle',cursor: 'pointer',transition: 'color 0.3s','&:hover': {color: token.colorPrimaryActive,},},lang: {width: 42,height: 42,lineHeight: '42px',position: 'fixed',right: 16,borderRadius: token.borderRadius,':hover': {backgroundColor: token.colorBgTextHover,},},container: {display: 'flex',flexDirection: 'column',height: '100vh',overflow: 'auto',backgroundImage:"url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",backgroundSize: '100% 100%',},};
});const Lang = () => {const { styles } = useStyles();return (<div className={styles.lang} data-lang>{SelectLang && <SelectLang />}</div>);
};const Login: React.FC = () => {const { initialState, setInitialState } = useModel('@@initialState');const { styles } = useStyles();const intl = useIntl();const fetchUserInfo = async () => {const userInfo = await initialState?.fetchUserInfo?.();if (userInfo) {flushSync(() => {setInitialState((s) => ({...s,currentUser: userInfo,}));});}};const handleSubmit = async (values: API.LoginParams) => {try {// 登录const response = await login({ ...values });if (response && response.success) {const defaultLoginSuccessMessage = intl.formatMessage({id: 'pages.login.success',defaultMessage: '登录成功!',});message.success(defaultLoginSuccessMessage);localStorage.setItem('token', response.token!);localStorage.setItem('refreshToken', response.refreshToken!);await fetchUserInfo();const urlParams = new URL(window.location.href).searchParams;history.push(urlParams.get('redirect') || '/');return;}} catch (error: any) {const defaultLoginFailureMessage = intl.formatMessage({id: 'pages.login.failure',defaultMessage: '登录失败,请重试!',});console.log(error);message.error(error?.response?.data?.message || defaultLoginFailureMessage);}};return (<div className={styles.container}><Helmet><title>{intl.formatMessage({id: 'menu.login',defaultMessage: '登录页',})}- {Settings.title}</title></Helmet><Lang /><divstyle={{flex: '1',padding: '32px 0',}}><LoginFormcontentStyle={{minWidth: 280,maxWidth: '75vw',}}logo={<img alt="logo" src="/logoipsum-295.svg" />}title={process.env.UMI_APP_APP_NAME || 'antd-ts-admin'}subTitle={intl.formatMessage({ id: 'pages.layouts.userLayout.title' })}onFinish={async (values) => {await handleSubmit(values as API.LoginParams);}}><><ProFormTextname="email"fieldProps={{size: 'large',prefix: <UserOutlined />,}}placeholder={intl.formatMessage({id: 'pages.login.username.placeholder',defaultMessage: '用户名',})}rules={[{required: true,message: (<FormattedMessageid="pages.login.username.required"defaultMessage="请输入用户名!"/>),},]}/><ProFormText.Passwordname="password"fieldProps={{size: 'large',prefix: <LockOutlined />,}}placeholder={intl.formatMessage({id: 'pages.login.password.placeholder',defaultMessage: '密码',})}rules={[{required: true,message: (<FormattedMessageid="pages.login.password.required"defaultMessage="请输入密码!"/>),},]}/></></LoginForm></div><Footer /></div>);
};export default Login;

表单内容是可以随时改的。

主要是 这里

 <ProFormTextname="email"fieldProps={{size: 'large',prefix: <UserOutlined />,}}placeholder={intl.formatMessage({id: 'pages.login.username.placeholder',defaultMessage: '用户名',})}rules={[{required: true,message: (<FormattedMessageid="pages.login.username.required"defaultMessage="请输入用户名!"/>),},]}/>

这里面有个

name=“email”

这里关系到提到给后端的参数。

还有一个 name=“password” 的

在这里插入图片描述
就是这里。

后端就要拿到 name 和 password

在这里插入图片描述
最后看下这里:

  const handleSubmit = async (values: API.LoginParams) => {try {// 登录const response = await login({ ...values });if (response && response.success) {const defaultLoginSuccessMessage = intl.formatMessage({id: 'pages.login.success',defaultMessage: '登录成功!',});message.success(defaultLoginSuccessMessage);localStorage.setItem('token', response.token!);localStorage.setItem('refreshToken', response.refreshToken!);await fetchUserInfo();const urlParams = new URL(window.location.href).searchParams;history.push(urlParams.get('redirect') || '/');return;}} catch (error: any) {const defaultLoginFailureMessage = intl.formatMessage({id: 'pages.login.failure',defaultMessage: '登录失败,请重试!',});console.log(error);message.error(error?.response?.data?.message || defaultLoginFailureMessage);}};

const response = await login({ …values });

这里有指定了请求路径和请求方法。

export async function login(body: API.LoginParams, options?: { [key: string]: any }) {return request<API.LoginResult>(`/auth/login`, {method: 'POST',headers: {'Content-Type': 'application/json',},data: body,...(options || {}),});
}

请求地址 /auth/login 要对上。还有请求方法 post

后端

在这里插入图片描述
上面都对了之后,就要拿到响应,

这里可以多用 console.log 输出一下,或看调试工具。

在这里插入图片描述
响应里是有 success: true ,用来判断刚刚好。

if (response && response.success) {

最后,就是把响应的 token 拿到并存起来。

localStorage.setItem(‘token’, response.token!);
localStorage.setItem(‘refreshToken’, response.refreshToken!);

基本上这样就完事了。

  • ant design pro 如何去保存颜色
  • ant design pro v6 如何做好角色管理
  • ant design 的 tree 如何作为角色中的权限选择之一
  • ant design 的 tree 如何作为角色中的权限选择之二
  • ant design pro access.ts 是如何控制多角色的权限的
  • ant design pro 中用户的表单如何控制多个角色
  • ant design pro 如何实现动态菜单带上 icon 的
  • ant design pro 的表分层级如何处理
  • ant design pro 如何处理权限管理
  • ant design pro 技巧之自制复制到剪贴板组件
  • ant design pro 技巧之实现列表页多标签

http://www.mrgr.cn/news/10270.html

相关文章:

  • Python 和 PyCharm 安装(傻瓜式)
  • C++基础语法:异常处理(二)
  • TS学习笔记
  • Cocos Creator2D游戏开发(15)---预制体和按钮的绑定以及冷却效果的实现
  • Docker数据卷使用手册
  • 【Excel】Excel小技巧(实时更新中)- 0.0.1
  • Linux文件编程(系统API调用)
  • 幅频特性曲线分析及使用WPF绘制
  • 2024手把收教你下载FL Studio 24.1.1.4239中文版破解版图文激活教程
  • Tcp VS Udp文件传输协议分析与比较
  • 深度学习----------------------残差网络ResNet
  • Unity-可分组折叠的Editor
  • wxpython Scintilla styledtextctrl滚动条拖到头文本内容还有很多的问题
  • 1058 选择题——PAT乙级
  • 前端学习Day35
  • 网络安全售前入门02——产品了解
  • ReTagList标签列表(API)
  • Solon2 接口开发:实战 Gateway 模式效果
  • K8S 1.31 新功能: 跨核分发CPU
  • 【图像处理】Retinex算法用于图像亮度增强