当前位置: 首页 > 后端技术 > Node.js

实战react技术栈+express前端博客项目(五)--前端前端实现登录功能

时间:2023-04-04 01:29:58 Node.js

实战react技术栈+express前端前端博客项目(五)--前端和前端实现登录功能项目地址:https://github.com/Nealyang/R...本来想等项目完成了再连载系列博客。随着开发的进行,确实遇到了很多坑,也请教了很多人。然后我想,为什么不在记录陷阱的同时分享收获。分享固然好,但如果能集思广益岂不更美。我们的口号是:坚决不做不完。本博客将为连载代码博客同步更新博客。以后随着项目的发展,可能会遇到之前写的不合适的地方,回去修改。如有不妥之处~欢迎兄弟们指教。谢谢!登录部分登录截图前端部分的实现延续上一篇文章。我们的登录界面已经画好了,登录功能涉及到异步请求。所以大致我需要以下操作。请求发起一个动作,请求结束一个动作,错误信息提醒动作,登录动作,注册动作,还有我们后面用到的不用登录的自动登录动作。因为login函数涉及到全局信息,所以这里我们放在index的reducer中处理constinitialState={isFetching:true,msg:{type:1,//0failure1successcontent:''},userInfo:{}};exportconstactionsTypes={FETCH_START:"FETCH_START",FETCH_END:"FETCH_END",USER_LOGIN:"USER_LOGIN",USER_REGISTER:"USER_REGISTER",RESPONSE_USER_INFO:"RESPONSE_USER_INFO",SET_MESSAGE:"SET_MESSAGE:"SET_MESSAGE"USER_AUTH"};exportconstactions={get_login:function(username,password){return{type:actionsTypes.USER_LOGIN,username,password}},get_register:function(data){return{type:actionsTypes.USER_REGISTER,data}},clear_msg:function(){return{type:actionsTypes.SET_MESSAGE,msgType:1,msgContent:''}},user_auth:function(){return{type:actionsTypes.USER_AUT}H}}};导出函数reducer(state=initialState,action){switch(action.type){caseactionsTypes.FETCH_START:return{...state,isFetching:true};caseactionsTypes.FETCH_END:return{...state,isFetching:false};案例actionsTypes.SET_MESSAGE:return{...state,isFetching:false,msg:{type:action.msgType,content:action.msgContent}};caseactionsTypes.RESPONSE_USER_INFO:return{...state,userInfo:action.data};默认:返回状态}}前端登录和注册动作发起classLoginFormComextendsComponent{}handleLogin=(e)=>{e.preventDefault();this.props.form.validateFields((错误,values)=>{if(!err){this.props.login(values.userName,values.password)}});};render(){const{getFieldDecorator}=this.props.form;return({getFieldDecorator('userName',{rules:[{required:true,message:'请输入用户名!'}],})(}placeholder="Username"/>)}{getFieldDecorator('密码',{rules:[{required:true,message:'请输入密码!'}],})(}type="密码”aceholder="密码"/>)}登录)}}constLoginForm=Form.create()(LoginFormCom);exportdefaultLoginForm如上代码,在handleLogin中,我们调用了父组件传入的login方法,这个方法可能叫做爷爷组件。仅此而已,它是容器组件。容器组件Home.js中的代码如下:Home.defaultProps={userInfo:{}};Home.propsTypes={userInfo:PropTypes.object.isRequired};函数mapStateToProps(state){return{userInfo:state.globalState.userInfo}}functionmapDispatchToProps(dispatch){return{login:bindActionCreators(actions.get_login,dispatch),register:bindActionCreators(actions.get_register,dispatch)}}导出默认连接(mapStateToProps,mapDispatchToProps)(Home);如上,我们定义了登录和注册。分别有登录和注册两种方式。在登录部分,我们编写如上。当然,注册功能也是如上。###登录和注册saga处理因为登录和注册是异步的,所以这里需要saga来监听这个action的发起。然后进行相应的处理。exportfunction*register(data){yieldput({type:IndexActionTypes.FETCH_START});try{returnyieldcall(post,'/user/register',data)}catch(error){yieldput({type:IndexActionTypes.SET_MESSAGE,msgContent:'注册失败',msgType:0});}finally{yieldput({type:IndexActionTypes.FETCH_END});}}exportfunction*registerFlow(){while(true){letrequest=yieldtake(IndexActionTypes.USER_REGISTER);letresponse=yieldcall(register,request.data);if(response&&response.code===0){yieldput({type:IndexActionTypes.SET_MESSAGE,msgContent:'注册成功!',msgType:1});yieldput({type:IndexActionTypes.RESPONSE_USER_INFO,data:response.data})}}}这里我们举一个registerFlow的例子,其实就是监听USER_REGISTER的动作。然后调用register方法,发送请求开始动作(界面出现Loading),然后请求结束动作。收到请求后,取出数据发送。获取数据后的动作基本思路如上,代码如上。请学习研究。不懂就直接issue。后半部分router.post('/register',(req,res)=>{let{userName,password,passwordRe}=req.body;if(!userName){responseClient(res,400,2,'用户名返回;}if(!password){responseClient(res,400,2,'密码不能为空');return;}if(password!==passwordRe){responseClient(res,400,2,'两次密码不一致');return;}//验证用户是否已经在数据库中User.findOne({username:userName}).then(data=>{if(data){responseClient(res,200,1,'用户名已经存在');return;}//保存到数据库letuser=newUser({username:userName,password:md5(password+MD5_SUFFIX),type:'user'});user.save().then(function(){User.findOne({username:userName}).then(userInfo=>{letdata={};data.username=userInfo.username;data.userType=userInfo.type;data.userId=userInfo._id;responseClient(res,200,0,'注册成功',data);返回;});})}).catch(err=>{responseClient(res);return;});});事实上,后端几乎是一样的。下面以注册为例简单说明一下上面的代码responseClient是一个封装的方法。代码如下:module.exports={MD5_SUFFIX:'eiowafnajkdlfjsdkfj姐夫文杰有事,我看你@#¥%...&)(*&...)',md5:function(pwd){letmd5=crypto.createHash('md5');returnmd5.update(pwd).digest('hex')},responseClient(res,httpCode=500,code=3,message='Serverexception',data={}){letresponseData={};responseData.code=代码;responseData.message=消息;responseData.data=数据;res.status(httpCode).json(responseData)}}让你可以缩短很多代码。然后判断用户名和密码是否为空,两个密码是否一致。(虽然这些部分前端也要判断,后端也要尽量保证)。验证用户是否已在数据库中。如果不存在,则存储并返回用户信息。如果存在,则将相应的信息返回给客户端。注意,因为我们这里使用了saga,只要HTTP请求中三次握手成功,我们就会返回200。对于重复用户名等错误,我们会在返回数据中统一标注状态码。存储时,我们使用md5加密。为了防止md5解密,我们在后面加了一个随机字符串。登录的时候,获取用户的登录密码,然后加上一个随机字符串,进行md5加密,然后与数据库数据内存进行比对,就OK了。以上就是后端实现的基本思路,接下来mongoose的基本操作这里就不多说了,大家可以自行查看文档。router.post('/login',(req,res)=>{let{username,password}=req.body;if(!username){responseClient(res,400,2,'用户名不能为空');return;}if(!password){responseClient(res,400,2,'密码不能为空');return;}User.findOne({username,password:md5(password+MD5_SUFFIX)}).then(userInfo=>{if(userInfo){//登录成功letdata={};data.username=userInfo.username;data.userType=userInfo.type;data.userId=userInfo._id;//登录成功后设置sessionreq.session.userInfo=data;responseClient(res,200,0,'登录成功',data);return;}responseClient(res,400,1,'用户名密码错误');}).catch(err=>{responseClient(res);})});##总结基础就到这里了,也就是实现了一个检查和添加的过程。也实现了前后端的基本交互。大家感受一下~然后大家一定发现了,登录后好像每次刷新都要重新登录,这不是我们想要的。当然,这部分功能,我们会在下一篇博客中介绍。##项目实现步骤系列博客[x]react实战技术栈+express前后端博客项目(0)——预热波[x]react实战技术栈+express前后端博客项目(一)——整体项目结构搭建、state状态树设计[x]实战react技术栈+express前端博客项目(二)——前端react-xxx、路由配置[x]实战react技术栈+express前端博客项目(3)--post端路由、proxy、静态资源托管等其他配置说明[x]实战react技术栈+express前后端博客项目(4)--博客首页代码编写与redux-saga组织[x]React实战react技术栈+express前后端博客项目(五)--React技术栈+express前后端博客项目(6)--使用session实现免登录+管理后台权限验证实战react技术栈+express前端博客项目(7)--前端管理界面用户查看功能+后端对应界面开发实战react技术栈+express前端博客项目(八)——前端管理界面标签管理功能+后端对应接口开发实战react技术栈+express前端博客项目(九)——前端管理界面评论管理功能+后台对应接口开发实战react技术栈+express前端博客项目(10)——前端管理界面发布功能实战react技术栈+express前端博客项目(11)--后台界面实战react技术栈+express前端博客项目对应文章部分的增删改查(十二)--发帖部分的前端改进(增删改查)、修改、分页等)实战react技术栈+express前端博客项目(十三)——发帖部分的前端改进(增删改查等)实战react技术栈+express前端博客项目(14)——内容详情页展示和阅读数实战react技术栈+express前端博客项目(15)——博客添加评论功能并实现react实战技术栈+express前后端博客项目(16)--pm2使用说明实战react技术栈+express前后端博客项目(17)--叫停##有事交流说的不是很清楚,或者需要和我交流,欢迎提issue。或者加群联系我~扫码关注我的个人微信公众号,直接回复,必有回复。分享更多原创文章。点击交流学习加我微信和qq群。一起学习,一起进步---欢迎兄弟们加入:Node.js技术交流群:209530601React技术栈:398240621前端技术聊:604953717(新)---