从零开始,搭建一个简单的购物平台(三)

从零开始,搭建一个简单的购物平台(二):https://blog.csdn.net/time_____/article/details/105408640
项目源码(持续更新):https://gitee.com/DieHunter/myCode/tree/master/shopping

这篇文章在上次的服务端登录基础上增加前端界面

在开始前我们可以简单用postman测试一下token和登录的功能,可以先在后端生成一段token从前端请求

验证token(成功和失败)

从零开始,搭建一个简单的购物平台(三)_第1张图片从零开始,搭建一个简单的购物平台(三)_第2张图片

紧接着验证一下用户登录(前提事先在数据库添加用户信息,添加过程及加密不做详细说明)
从零开始,搭建一个简单的购物平台(三)_第3张图片

测试成功后我们开始配置编写前端部分(只实现功能,对界面要求不高)

文件结构:

从零开始,搭建一个简单的购物平台(三)_第4张图片

  • 配置config.js文件夹,新建config.js文件用于存放配置常量(和服务端config.js一样)
    export default class Config {
      static Agreement = "http://";
      static BaseUrl = "127.0.0.1";
      static ServerUrl = "";
      static ServerPort = ":1024";
      static Path = "/";
      static CryptoKey = "tokenkey";//加密信息关键字
      static FilePath = this.Agreement + this.BaseUrl + this.ServerPort + this.Path;
      static ServerApi = {//接口名
        token: "checkToken",
        user: {
          userLogin: "user/userLogin",
        }
      };
      static StorageName = {//本地缓存localstorage名称
        token: "token",
        userInfo: "userInfo"
      };
    }
  • 在utils文件中新建方法,将其放在react.component的原型中,使继承组件可以直接调用
    storage:
    import { Component } from "react";
    class Utils {
      static saveStorage(key, val) {//添加缓存
        localStorage.setItem(key, JSON.stringify(val));
      }
      static getStorage(key) {//获取缓存
        try {
          return JSON.parse(localStorage.getItem(key));
        } catch (error) {}
      }
      static clearStorage(key) {//清除缓存
        try {
          localStorage.removeItem(key);
        } catch (error) {}
      }
    }
    Component.prototype.$utils = Utils;
    

    axios:

    import Config from "../config/config";
    import Axios from "axios";
    import { Component } from "react";
    import { message } from "antd";
    Axios.defaults.baseURL =
      Config.Agreement + Config.BaseUrl + Config.ServerPort + Config.Path;
    // 添加请求拦截器
    Axios.interceptors.request.use(
      function (config) {
        // 在发送请求之前做些什么
        return config;
      },
      function (error) {
        // 对请求错误做些什么
        return Promise.reject(error);
      }
    );
    // 添加响应拦截器
    Axios.interceptors.response.use(
      function (response) {
        // 对响应数据做点什么
        if (response.data.result === -999) {
          //token验证失败
          return message.error(response.data.msg);
        }
        return response.data;
      },
      function (error) {
        console.log(error)
        // 对响应错误做点什么
        message.error("操作失败");
        return Promise.reject(error);
      }
    );
    
    Component.prototype.$axios = Axios;
    

    Crypto:

    import * as CryptoJS from "crypto-js";
    import { Component } from "react";
    import config from "../config/config";
    const { CryptoKey } = config;
    class CryptoTool {
      /* Crypto加密方法
       * @param {object} _data       对用户请求后端的参数进行加密
       */
      static setCrypto(_data) {
        let key = CryptoJS.enc.Utf8.parse(CryptoKey);
        let encrypted = CryptoJS.AES.encrypt(JSON.stringify(_data), key, {
          mode: CryptoJS.mode.ECB,
          padding: CryptoJS.pad.Pkcs7
        });
        return encrypted.toString();
      }
       /* Crypto解密方法
       * @param {string} _token       将秘文解密成对象形式
       */
      static getCrypto(_token) {
        let key = CryptoJS.enc.Utf8.parse(CryptoKey);
        let decrypt = CryptoJS.AES.decrypt(_token, key, {
          mode: CryptoJS.mode.ECB,
          padding: CryptoJS.pad.Pkcs7
        });
        return JSON.parse(CryptoJS.enc.Utf8.stringify(decrypt).toString());
      }
    }
    Component.prototype.$crypto = CryptoTool;
    

     

  • 在index.js中添加这些函数
    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./App";
    import "./util/axios";
    import "./util/utils";
    import "./util/cryptoTool";

     

  •  随后在page/login中新增login.js,简单配置一下login页面后,在App.js中引入login页面
    import React from "react";
    import Login from "./page/login/login"
    
    function App() {
      return (
        
    ); } export default App;
  • 在antd官网找到登录界面实例,直接把大部分复制到login界面,用less微调一下后实现以下界面
    从零开始,搭建一个简单的购物平台(三)_第5张图片 从零开始,搭建一个简单的购物平台(三)_第6张图片
  • login.js
    import React from "react";
    import "./login.less";
    import { Card, Form, Input, Button, Checkbox, message } from "antd";
    import { UserOutlined, LockOutlined } from "@ant-design/icons";
    import config from "../../config/config";
    const { ServerApi, StorageName } = config;
    export default class Login extends React.Component {
      constructor(props) {
        super(props);
        this.checkToken(); //验证用户token是否过期
      }
      render() {
        return (
          
    } placeholder="用户名/邮箱" /> } type="password" placeholder="密码" /> 3天内免密 忘记密码 或者注册
    ); } checkToken() { let token = this.$utils.getStorage(StorageName.token); if (!token) return; this.$axios .get(ServerApi.token, { params: { token }, }) .then((res) => { switch (res.result) { case 1: message.success(res.msg).then(() => { // this.props.history.push({ // pathname: "/admin/findshop", // query: res, // }); }); break; default: // message.warning(res.msg); break; } }) .catch((err) => { console.log(err); }); } sendData = (data) => { this.$axios .get(ServerApi.user.userLogin, { params: { crypto: this.$crypto.setCrypto(data) }, }) .then((res) => { switch (res.result) { case 1: this.$utils.saveStorage(StorageName.token, res.token); message.success(res.msg); // this.props.history.push({ // pathname: "/admin/findshop", // query: res, // }); break; default: message.warning(res.msg); break; } }) .catch((err) => { console.log(err); }); }; }
  • 效果如下:
    从零开始,搭建一个简单的购物平台(三)_第7张图片从零开始,搭建一个简单的购物平台(三)_第8张图片从零开始,搭建一个简单的购物平台(三)_第9张图片

用户token验证,登录功能前端+后端基本实现

总结

前端与后端的项目搭建顺序可能有所不同,项目周期可能也不同,这时需要灵活使用前后端数据模拟和请求模拟工具,前端可以使用easymock和mockjs生成假数据,而后端最简单的直接放到浏览器url访问(仅限于get),或者使用postman,SoapUI等接口测试工具

你可能感兴趣的:(Node.js,Vue,React,mongodb,node.js,reactjs)