实战react技术栈+express前后端博客项目(6)-- 使用session实现免登陆+管理后台权限验证

前端之家收集整理的这篇文章主要介绍了实战react技术栈+express前后端博客项目(6)-- 使用session实现免登陆+管理后台权限验证前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

项目地址:https://github.com/Nealyang/R...

本想等项目做完再连载一波系列博客,随着开发的进行,也是的确遇到了不少坑,请教了不少人。遂想,何不一边记录踩坑,一边分享收获呢。分享当然是好的,
如果能做到集思广益,那岂不是更美。我们的口号是:坚决不会烂尾

博客为连载代码博客同步更新博客,随着项目往后开发可能会遇到前面写的不合适的地方会再回头修改。如有不妥~欢迎兄弟们不啬赐教。谢谢!

session@H_404_20@

后端部分

上一篇文章中,我们已经实现了前后端的登录功能。问题大家可能都已经发现了,当刷新页面的时候,之前登录过的现在得重新登录。显然,这个并不是我们想想要的。

所以这里我们采用session的机制来解决这类问题。不了session和coolie可以参考我这篇博客

apiServer.js

  1. app.use(cookieParser('express_react_cookie'));
  2. app.use(session({
  3. secret:'express_react_cookie',resave: true,saveUninitialized:true,cookie: {maxAge: 60 * 1000 * 30}//过期时间
  4. }));

因为是登录信息,所以这里我们采用的是session。首先需要在apiServer.js中引入cookie-parser和express-session中间件。

coolieParser里面设置一个key,必须要和session中一致。然后设置coolie的过期时间。这里我们设置为30min。

然后再用户登录成功了以后,我们需要设置session

  1. router.post('/login',(req,res) => {
  2. let {username,password} = req.body;
  3. if (!username) {
  4. responseClient(res,400,2,'用户名不可为空');
  5. return;
  6. }
  7. if (!password) {
  8. responseClient(res,'密码不可为空');
  9. return;
  10. }
  11. User.findOne({
  12. username,password: md5(password + MD5_SUFFIX)
  13. }).then(userInfo => {
  14. if (userInfo) {
  15. //登录成功
  16. let data = {};
  17. data.username = userInfo.username;
  18. data.userType = userInfo.type;
  19. data.userId = userInfo._id;
  20. //登录成功后设置session
  21. req.session.userInfo = data;
  22.  
  23. responseClient(res,200,'登录成功',data);
  24. return;
  25. }
  26. responseClient(res,1,'用户名密码错误');
  27.  
  28. }).catch(err => {
  29. responseClient(res);
  30. })
  31. });

其中,
req.session.userInfo = data即为设置session的userInfo。

然后再server端需要另写一个接口。在用户打开网站的时候就发起请求,验证用户是否已经登录

  1. //用户验证
  2. router.get('/userInfo',function (req,res) {
  3. if(req.session.userInfo){
  4. responseClient(res,'',req.session.userInfo)
  5. }else{
  6. responseClient(res,'请重新登录',req.session.userInfo)
  7. }
  8. });

很简单,就是将请求中的req.session.userInfo的信息返回过去。这样,当用户访问网站的时候,先发送这个请求,来判断用户知否已经登陆过。如果已经登陆过,拿到这个userInfo直接put一个action到reducer中,修改state状态树即可。

前端部分

前端部分比较常规。在最外层的container中,直接发送请求即可

  1. class AppIndex extends Component {
  2.  
  3. constructor(props) {
  4. super(props);
  5. this.openNotification = this.openNotification.bind(this);
  6. this.shouldComponentUpdate = PureRenderMixiin.shouldComponentUpdate.bind(this);
  7. }
  8.  
  9. openNotification(type,message) {
  10. let that = this;
  11. notification[type]({
  12. message: message,onClose: () => {
  13. that.props.clear_msg();
  14. }
  15. });
  16. that.props.clear_msg();
  17. };
  18.  
  19. render() {
  20. let {isFetching} = this.props;
  21. return (
  22. <Router>
  23. <div>
  24. <Switch>
  25. <Route path='/404' component={NotFound}/>
  26. <Route path='/admin' component={Admin}/>
  27. <Route component={Front}/>
  28. </Switch>
  29. {isFetching && <Loading/>}
  30. {this.props.notification && this.props.notification.content ?
  31. (this.props.notification.type === 1 ?
  32. this.openNotification('success',this.props.notification.content) :
  33. this.openNotification('error',this.props.notification.content)) :
  34. null}
  35. </div>
  36. </Router>
  37. )
  38. }
  39.  
  40. componentDidMount() {
  41. this.props.user_auth();
  42. }
  43.  
  44. }

然后对应saga的处理也比较常规,这里不再赘述。

权限认证@H_404_20@

因为是博客系统,所以所谓的权限就是判断改登录用户是否为管理员。我们在设计user表的时候,添加了身份一项。当然,咱可以随意用别的字符来标识管理员和普通用户

  1. render() {
  2. const {url} = this.props.match;
  3. if(this.props.userInfo.userType){
  4. return (
  5. <div>
  6. {
  7. this.props.userInfo.userType === 'admin' ?
  8. <div className={style.container}>
  9. <div className={style.menuContainer}>
  10. <AdminMenu history={this.props.history}
  11. url={this.props.adminUrl}
  12. changeUrl={this.props.change_location_admin}/>
  13. </div>
  14. <div className={style.contentContainer}>
  15. <Switch>
  16. <Route exact path={url} component={AdminIndex}/>
  17. <Route path={`${url}/managerUser`} component={AdminManagerUser}/>
  18. <Route path={`${url}/managerTags`} component={AdminManagerTags}/>
  19. <Route path={`${url}/newArticle`} component={AdminNewArticle}/>
  20. <Route path={`${url}/detail`} component={Detail}/>
  21. <Route component={NotFound}/>
  22. </Switch>
  23. </div>
  24. </div> :
  25. <Redirect to='/'/>
  26. }
  27. </div>
  28. )
  29. }else{
  30. return <NotFound/>
  31. }
  32. }

在admin.js中,我们判断state中是否有userInfo这个选项。


如果userInfo是有值的,那么说明已经登录。如果没有值,则跳转到NotFound页面

为什么先显示notFound界面,而不是在userInfo为空的时候直接Redirect?

这里有个大坑,具体看我segmentFault上的提问:react redux身份验证,取state的问题

以上即为admin的权限认证,如上,当admin登录到管理后天的时候,既可以到管理界面,当不是admin登录到管理后台的时候,会直接Redirect到博客首页

总结@H_404_20@

如上,我们就直线了用户的免登陆以及权限管理的问题。主要就是通过session和状态树的判断。
下一篇,我们就开始后端部分的开发~

## 项目实现步骤系列博客

## 交流

倘若有哪里说的不是很明白,或者有什么需要与我交流,欢迎各位提issue。或者加群联系我~

扫码关注我的个人微信公众号,直接回复,必有回应。分享更多原创文章。点击交流学习加我微信、qq群。一起学习,一起进步

---

欢迎兄弟们加入:

Node.js技术交流群:209530601

React技术栈:398240621

前端技术杂谈:604953717 (新建)

---

猜你在找的React相关文章