next.js搭建博客系统-04-登录模块(验证码和登录)

1,110 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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,
        },
      });

点击登录,即可登录成功。