1. 登录注册移动端WEB页面(组件)结构搭建
2. 基本的请求,登陆注册页面跳转交互
3. 注册请求
使用redux和axios配合发送请求,更新数据,提示错误信息
(1)新建user.redux.js文件,设置初始注册字段
const initState = {
_id: '',
isAuth: false,
msg: '',
user: '',
pwd: '',
type: ''
};
(2)实现流程:
2-1. 在register.js 中引入connect装饰器,然后调用state.user,引入注册方法register
2-2. 在点击注册按钮后,执行this.props.register ( 注册字段参数对象 );
2-3. 然后判断,发送POST请求,请求成功或失败dispath更新对应成功或失败状态对象值
2-4. 源代码参考
import React,{ Component } from 'react';
import Logo from '../../component/logo/logo.js';
import { List, InputItem, WhiteSpace, WingBlank, Button, Radio } from 'antd-mobile';
import { Redirect } from 'react-router-dom'
import { connect } from 'react-redux'
import { register } from '../../redux/user.redux.js'
import './register.css'
@connect(
state=>state.user,
{ register }
)
class Register extends Component{
constructor(props){
super(props);
this.state = {
user: '',
pwd: '',
repwd: '',
type: 'boss' //or boss
}
}
render(){
const RadioItem = Radio.RadioItem;
return (
<div className="registerPage">
<Logo />
{ this.props.redirect ? <Redirect to={this.props.redirect} /> : null }
{ this.props.msg ? <p className="warnInfo">{this.props.msg}</p> : null }
<WingBlank>
<List>
<InputItem type="text"
onChange={ v=>this.handleChange('user',v) }
>用户名</InputItem>
<InputItem type="password"
onChange={ v=>this.handleChange('pwd',v) }
>密码</InputItem>
<InputItem type="password"
onChange={ v=>this.handleChange('repwd',v) }
>确认密码</InputItem>
</List>
<WhiteSpace />
<RadioItem
checked={ this.state.type == 'genius' }
onClick={ v=>this.handleChange('type','genius') }
>谷歌</RadioItem>
<WhiteSpace />
<RadioItem
checked={ this.state.type == 'boss' }
onClick={ v=>this.handleChange('type','boss') }
>微信</RadioItem>
<WhiteSpace />
<Button type="primary" onClick={this.handleRegister}>注册</Button>
</WingBlank>
</div>
)
}
handleChange=(key,value)=>{
this.setState({
[key]: value
})
}
handleRegister=()=>{
this.props.register(this.state);
//console.log(this.state);
}
}
export default Register;
4. 设计mongodb用户数据表
(1)连接数据库
(2)定义数据库模型
(3)设计数据表user:字段(用户名[require],密码[require],类别[require],头像,简介,公司,薪酬)
(4)批量创建数据表,导出数据库模型对象
(5)node接收请求的文件中,引入模型对象,实现数据库查询等操作
(6)node文件接收注册请求,引入body-parser、cookie-parser 中间件
(7)基本后端的用户请求响应处理:
const app = require('express');
const utility = require('utility');
const router = app.Router();
const UserModel = require('../model.js');
const User = UserModel.getModel('user');
const filter = { pwd:0, __v:0 }
router.get('/info',function(req,res,next){
//1. cookie校验
//res.json({ 'name': 'admin','isLogin': false });
let cookie = req.cookies;
if(!cookie.userid){
return res.json({code:1,isLogin:false,msg:'用户未登录'});
}
//查询该用户ID是否存在
User.findOne({_id:cookie.userid},filter,function(err,doc){
if(err){
return res.json({code:1,isLogin:false,msg:'服务器出现错误'});
}
return res.json({code:0,isLogin:true,msg:'用户已登陆',data:doc});
})
});
// 注册响应 /user/register
router.post('/register',function(req,res){
const {user, pwd, type} = req.body;
//查询是否已经存在该用户
User.findOne({user},(err,doc)=>{
if(doc){
return res.json({code:1,msg:'该用户已存在'})
}
let userModel = new User({user, type, pwd: encryption(pwd) });
userModel.save((err,doc)=>{
if(err){
return res.json({code:1,msg:'服务器出现错误'})
}
res.cookie('userid',doc._id);
return res.json({code:0,msg:'注册成功'})
})
})
});
// 登陆响应 /user/login
router.post('/login',(req,res)=>{
const {user, pwd} = req.body;
//查询是否能够匹配用户名密码保持一直的字段
User.findOne({user,pwd:encryption(pwd)},filter,(err,doc)=>{
if(doc){
res.cookie('userid',doc._id);
return res.json({code:0,msg:'登陆成功',data:doc})
}
return res.json({code:1,msg:'用户名或密码错误'})
})
})
router.get('/list',function(req,res,next){
User.find({},function(err,doc){
return res.json(doc);
})
});
router.get('/remove',function(req,res,next){
User.remove({},function(err,doc){
return res.json(doc);
})
});
//加密
function encryption(pwd){
//默认前缀
var front = '!!!WEB#@2018_account_';
return utility.md5(utility.md5(front+pwd));f
}
module.exports = router;
(8)后台密码加密( utility模块 自定义字符串md5双重加密 )
function encryption(pwd){
//默认前缀
var front = '!!!WEB#@2018_account_';
return utility.md5(utility.md5(front+pwd));f
}
(9)注册完,更新redux数据,定义路由跳转
export function getRedirect(type,avator){
var route = '/'+type;
//判断是否已完善信息
if(!avator){
route = '/'+type+'info';
}
return route;
}
(10)登录前后端响应
(11)前后端:
1) 登陆注册成功生成cookie,保存为userid字段
2) 每次除/login及/register的路由请求,后端验证是否存在cookie,且返回是否处于登陆状态
3) 结合redux,更新当前的状态树的用户信息
import React,{ Component } from 'react';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { loadData } from '../../redux/user.redux.js'
@withRouter
@connect(
state=>state.user,
{ loadData }
)
class AuthRoute extends Component{
componentDidMount() {
//1. 获取用户信息
//3. 现在的url地址 如果是login、register页面不需要加载用户数据
const publicList = ['/login','/register'];
const pathName = this.props.location.pathname;
if( publicList.indexOf(pathName) > -1){
return false;
}
//4. 用户的tyoe 身份是Boss还是牛人
//5. 用户是否完善信息 ( 选择头像 个人简介 )
this.$axios.get('/user/info').then(res=>{
if(res.code == 0 && res.status == 200){
//2. 判断是否登陆
if(res.data.isLogin){
//处于登录状态
this.props.loadData({...res.data,isAuth:true});
}else{
//没有登录 跳转到登录页面
this.props.history.push('/login');
}
}
})
}
render(){
return null
}
}
export default AuthRoute;