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

server/2024/10/19 3:33:43/

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

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

我的网站

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

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

例如我的:

javascript">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 呢:

参考下我的

javascript">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

javascript">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;

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

主要是 这里

javascript"> <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

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

javascript">  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 });

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

javascript">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.ppmy.cn/server/104378.html

相关文章

科研绘图系列:Python语言时间趋势图

介绍 不同指标在时间上的变化,可以用时间序列线图表示趋势。 加载Python包 import sys import pandas as pd import numpy as np import scipy as sp from scipy import stats import randomimport seaborn as sns import matplotlib.pyplot as plt from matplotl

Qt+ffmpeg环境搭建

Qtffmpeg环境搭建 各平台常见视频开发库举例: iOS&#xff1a;AVFoundation AudioUnitAndroid&#xff1a;MediaPlayer&#xff0c;MediaCodecWindows&#xff1a;DirectShowLinux&#xff1a;GStreamer FFmpeg 库是一个跨平台的视频开发库, 还有 libVLC 也是一个跨平台的视频开…

vue3模拟生成并渲染10万条数据,并实现本地数据el-table表格分页

效果图&#xff1a; 一点都不卡 话不多说&#xff0c;直接上码 <template><div class"container"><h3 class"table-title">el表格 分页</h3><el-table :data"tableList.slice((currentPage-1)*pageSize, currentPage*p…

Information Processing Technician

信息处理技术员试题 🔥SeptemberZone 1.信息是一种() A.资源 B.物质 C.能量 D.载体 2.以下关于信息的表达中,不正确的选项是() A.一切数据都能产生信息 B.信息的产生、处理和传递依靠于物质和能量 C.同一信息在不同的时间可能具有不同的价值 D.信息的屡次使用不会使信息…

Redis (day 3)

一、通过jedis连接数据库 1.首先导入依赖 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.1.0</version></de…

XML 实例:深入解析与实际应用

XML 实例&#xff1a;深入解析与实际应用 XML&#xff08;可扩展标记语言&#xff09;是一种用于存储和传输数据的标记语言。它由万维网联盟&#xff08;W3C&#xff09;开发&#xff0c;并已成为在不同系统和应用程序之间交换数据的标准格式。本文将提供对XML的深入解析&…

【Kubernetes】K8s中Container(容器)、Pod(小组)和node(节点)概念讲解

Kubernetes学习之路 第一章 Kubernetes学习入门之Container(容器)、Pod(小组)和node(节点)概念 文章目录 Kubernetes学习之路前言一、Container&#xff08;容器&#xff09;二、Pod&#xff08;小组&#xff09;1.单容器 Pod2.多容器 Pod 三、Container&#xff08;容器&…

前端架构:使用不同框架构建可扩展的大型应用

前端架构在构建可扩展的大型应用中扮演着至关重要的角色。随着前端技术的不断发展和业务需求的日益复杂&#xff0c;单一的前端框架往往难以满足大型应用的所有需求。因此&#xff0c;使用不同框架构建可扩展的大型应用成为了一种常见的做法。以下将详细探讨这种前端架构的优势…