ゼロから始めて、簡単なショッピングプラットフォームを構築します(2):https://blog.csdn.net/time_____/article/details/105408640
プロジェクトのソースコード(継続的な更新):https://gitee.com/DieHunter/myCode/ツリー/マスター/ショッピング
この記事では、最後のサーバーログインに基づいてフロントエンドインターフェイスを追加します
始める前に、postmanを使用してトークンとログインの機能をテストし、バックエンドでトークンを生成してフロントエンドから要求することができます。
検証トークン(成功と失敗)
次に、ユーザーログインを確認します(ユーザー情報が事前にデータベースに追加されている場合、追加プロセスと暗号化については詳しく説明しません)。
テストが成功した後、フロントエンド部分の構成と書き込みを開始します(機能のみを実現し、インターフェイスの高い要件は実現しません)
ファイル構造:
- 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のプロトタイプに配置して、継承されたコンポーネントがストレージを直接呼び出すことができるようにし
ます。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;
暗号:
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を追加し、ログインページを構成した後、App.jsにログインページを導入します。
import React from "react"; import Login from "./page/login/login" function App() { return ( <div className="App"> <Login></Login> </div> ); } export default App;
- antdの公式ウェブサイトでログインインターフェイスインスタンスを見つけ、それらのほとんどを直接ログインインターフェイスにコピーし、使用量を減らして次のインターフェイスを微調整します。
- 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 ( <div className="cardBox"> <Card title="登录"> <Form name="normal_login" className="login-form" initialValues={ { remember: true }} onFinish={this.sendData} > <Form.Item name="username" rules={[ { required: true, message: "请输入用户名/邮箱", }, ]} > <Input className="infoInput" prefix={<UserOutlined className="site-form-item-icon" />} placeholder="用户名/邮箱" /> </Form.Item> <Form.Item name="password" rules={[ { required: true, message: "请输入密码", }, ]} > <Input className="infoInput" prefix={<LockOutlined className="site-form-item-icon" />} type="password" placeholder="密码" /> </Form.Item> <Form.Item> <Form.Item name="remember" valuePropName="checked" noStyle> <Checkbox>3天内免密</Checkbox> </Form.Item> <a className="login-form-forgot" href="#aaa"> 忘记密码 </a> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit" className="login-form-button" > 登录 </Button> 或者<a href="#aaa">注册</a> </Form.Item> </Form> </Card> </div> ); } 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); }); }; }
- 効果は次のとおりです。
ユーザートークンの検証、ログイン機能のフロントエンド+バックエンドの基本的な実現
総括する
フロントエンドプロジェクトとバックエンドプロジェクトの構築順序やプロジェクトサイクルが異なる場合があります。この場合、フロントエンドとバックエンドのデータシミュレーションを使用し、シミュレーションツールを柔軟にリクエストする必要があります。フロントエンドはeasymockとmockjsを使用して偽のデータを生成でき、バックエンドは最も簡単に直接配置できます。ブラウザのURLアクセス(取得のみ)、またはpostman、SoapUI、その他のインターフェイステストツールを使用する