import * as React from 'react' import * as ReactDom from 'react-dom' import {Link, browserHistory} from 'react-router'; import * as axios from 'axios'; export default class Login extends React.Component<any,any>{ constructor(props){ super(props) this.state = { userName : '', password : '', yzNoId : '', hash : Math.random() } } public async sbumit(params : any) : Promise<any>{ let res = await axios.post('http://localhost:3000/login',params); } handleUserName(e) : any { this.setState({ userName : e.target.value }) } handlePassword(e) : any { this.setState({ password : e.target.value }) } handleYzId(e) : any { this.setState({ yzNoId : e.target.value }) } setHash() { this.setState({ hash : Math.random() }) } render(){ const { userName, password, yzNoId } = this.state; return( <div> <div className="nav-wrap"> <ul className="nav"> <li><Link to="/home">首页</Link></li> <li><Link to="/imgLoad">上传</Link></li> <li><Link to="/login">登陆</Link></li> </ul> </div> <div className="content"> <div className="login-warp"> <p> <input type="text" className="username" value=https://www.jb51.net/article/{userName} onChange=https://www.jb51.net/article/{this.handleUserName.bind(this)} placeholder="用户名"/> </p> <p> <input type="text" className="password" value=https://www.jb51.net/article/{password} onChange=https://www.jb51.net/article/{this.handlePassword.bind(this)} placeholder="密码"/> </p> <p> <input type="text" className="yz" value=https://www.jb51.net/article/{yzNoId} onChange=https://www.jb51.net/article/{this.handleYzId.bind(this)} placeholder="验证码"/> <img src=https://www.jb51.net/article/{"http://localhost:3000/captcha?aaa="+this.state.hash} className="yz-img" onClick=https://www.jb51.net/article/{this.setHash.bind(this)} /> </p> <p> <input type="button" className="submit" value="登陆" onClick=https://www.jb51.net/article/{this.sbumit.bind(this,{userName:userName,password:password,captcha:yzNoId})} /> </p> </div> </div> </div> ) } }
这样只要点击img,就会随机生成一个hash,然后就会调用新的图片出来。
接着我们进行登录验证。
loginer方法就是进行登录验证的。
拿到用户的用户名信息,密码以及验证码一次对比,最后返回登录是否成功数据。
当用户登陆成功以后,下次登录就不需要再次登录了,以往的方法可以选则session或者cookie的方式,在这里我们使用token。因为现在已经实现了前后端分离开发,我们更倾向于构建单页面配合ajax构建应用。而token最适合这种开发模式不过了。
token登录验证
token是一串经过加密的字符串,登录成功以后返回给用户保存,然后用户在请求接口时,都带这个token。所以我们需要对token进行加密。
Json Web Token就是专门解决这个问题的,原理就不做详解了,其实就是按照一定的方式得到一个字符串,然后在通过某种方式解开。
我们要做的第一步就是
当用户登录成功后,创建一个token返回给用户。
第二步:用户拿到token后应该把token存到本地。
第三步:需要写一个中间层,每次用户请求时我们验证用户携带的token是否正确。正确返回数据,不正确返回警告。
用户每次请求数据的时候要在header里把token带上。
第一步:还是controller/login.js
var rf = require('fs'); var jwt = require('jsonwebtoken'); var captchapng = require('captchapng'); var Tokens = require('../middleware/token') var t = new Tokens; class Login { constructor(){} captcha(req, res, next) { var str = parseInt(Math.random()*9000+1000); //随机生成数字 req.session.captcha = str; // 存入session var p = new captchapng(80, 30, str); //生成图片 p.color(0, 0, 0, 0); p.color(80, 80, 80, 255); var img = p.getBase64(); var imgbase64 = new Buffer(img, 'base64'); res.writeHead(200, { 'Content-Type': 'image/png' }); res.end(imgbase64); } loginer(req, res, next) { let captcha = req.body.captcha; let userName = req.body.userName; let password = req.body.password; if (captcha != req.session.captcha) { res.status(400).send({ message: '验证码错误' }); }else if(userName == "chenxuehui" && password == "123321"){ // 设置token var datas = {userName:"chenxuehui"} //调用../middleware/token 下方法设置 var token = t.setToken('cxh',300,datas) res.json({"code":100,"verson":true,"msg":"登陆成功","token":token}); }else{ res.json({"code":0,"verson":false,"msg":"密码错误"}); } } } module.exports = Login
这次在loginer方法里面我们加入设置token,并返回给用户。setToken方法是设置token的方法。
第二步:用户拿到后保存。
在login.tsx就变成如下