携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
上篇文章实现了登录组件中的登录弹窗功能
接下来继续实现登录组件中的获取验证码功能
验证码获取
接下来开始编辑 获取 验证码 接口的逻辑
这里采用 云 的 验证码接口
1.根据 云的 接入文档,拼成url
const session: ISession = req.session;
const { to = '', templateId = '1' } = req.body;
const AppId = '8aaf0708825efdb2018278a5e95c02271a';
const AccountId = '8aaf0708825efdb201827812a5e8750713';
const AuthToken = 'xx';
const NowDate = format(new Date(), 'yyyyMMddHHmmss');
const SigParameter = md5(`${AccountId}${AuthToken}${NowDate}`);
const Authorization = encode(`${AccountId}:${NowDate}`);
const verifyCode = Math.floor(Math.random() * (9999 - 1000)) + 1000;
const expireMinute = '5';
const url = `https://app.cloopen.com:8883/2013-12-26/Accounts/${AccountId}/SMS/TemplateSMS?sig=${SigParameter}`;
2.使用request调用接口,参数 to 代表手机号,templateId 代表是 通过手机号进行登录,appId和datas按文档传入
const response = await request.post(
url,
{
to,
templateId,
appId: AppId,
datas: [verifyCode, expireMinute],
},
{
headers: {
Authorization,
},
}
);
4.获取 response,根据response 进行处理。当接口调用成功的时候,将验证码保存到session中,同时返回200状态码和成功的数据,当失败的时候,返回失败的原因
const { statusCode, templateSMS, statusMsg } = response as any;
if (statusCode === '000000') {
session.verifyCode = verifyCode;
await session.save();
res.status(200).json({
code: 0,
msg: statusMsg,
data: {
templateSMS
}
});
} else {
res.status(200).json({
code: statusCode,
msg: statusMsg
});
}
5.当验证码调成功的时候,显示 倒计时
request
.post('/api/user/sendVerifyCode', {
to: form?.phone,
templateId: 1,
})
.then((res: any) => {
if (res?.code === 0) {
setIsShowVerifyCode(true);
} else {
message.error(res?.msg || '未知错误');
}
});
效果如下:
开始倒计时,并成功收到验证码
登录逻辑
当成功获取验证码,然后开始进行登录
在用户输入手机号和验证码,点击登录按钮的时候,去调用登录的接口
接口为:/api/user/login
传入表单数据,当成功的时候 将 用户的信息 存入到 store中,并且调用 onClose 将弹窗关闭
const handleLogin = () => {
request
.post('/api/user/login', {
...form,
identity_type: 'phone',
})
.then((res: any) => {
if (res?.code === 0) {
// 登录成功
store.user.setUserInfo(res?.data);
onClose && onClose();
} else {
message.error(res?.msg || '未知错误');
}
});
};
接下来开始编写 登录接口的逻辑
1.首先从session中获取验证码
const session: ISession = req.session;
2.从body中获取传入的验证码
const { phone = '', verify = '', identity_type = 'phone' } = req.body;
3.比较两个验证码是否相等,如果不相等,则返回 验证码错误
4.如果两个验证码相等,则去用户表中查找,判断用户是否存在,如果用户不存在,则表示注册,如果存在,则表示登录。
// 验证码正确,在 user_auths 表中查找 identity_type 是否有记录
const userAuth = await userAuthRepo.findOne(
{
identity_type,
identifier: phone,
},
{
relations: ['user'],
}
);X!
5.当用户存在的时候,从数据库中读取除用户信息,存入session和cookie中,并将用户信息返回
// 已存在的用户
const user = userAuth.user;
const { id, nickname, avatar } = user;
session.userId = id;
session.nickname = nickname;
session.avatar = avatar;
await session.save();
setCookie(cookies, { id, nickname, avatar });
res?.status(200).json({
code: 0,
msg: '登录成功',
data: {
userId: id,
nickname,
avatar,
},
});
6.当用户不存在的时候,将输入的信息 存入到数据库,session和 cookie中,表示用户注册,返回用户信息
// 新用户,自动注册
const user = new User();
user.nickname = `用户_${Math.floor(Math.random() * 10000)}`;
user.avatar = '/images/avatar.jpg';
user.job = '暂无';
user.introduce = '暂无';
const userAuth = new UserAuth();
userAuth.identifier = phone;
userAuth.identity_type = identity_type;
userAuth.credential = session.verifyCode;
userAuth.user = user;
const resUserAuth = await userAuthRepo.save(userAuth);
const {
user: { id, nickname, avatar },
} = resUserAuth;
session.userId = id;
session.nickname = nickname;
session.avatar = avatar;
await session.save();
setCookie(cookies, { id, nickname, avatar });
res?.status(200).json({
code: 0,
msg: '登录成功',
data: {
userId: id,
nickname,
avatar,
},
});
点击登录,即可登录成功。