登录功能实现

登录模板包括登录、登出、购物车数量查询、全局拦截

routes/user.js

引入user模型

var User = require('./../models/user');

 

登录以后需要将用户信息保存到cookie

在app.js中引入cookie-parser插件,专门处理cookie

var cookieParser = require('cookie-parser');

在app.js中引入body-parser,主要对post请求做json转换

var bodyParser = require('body-parser');

app.use(bodyParser.json());

app.use(cookieParser());

因为有了cookie-parser,我们可以做一些cookie的存取

 

增加转发

node后端登录 routes/user.js

var express = require('express');
var router = express.Router();

var User = require('./../models/user');

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

router.get('/test', function(req, res, next) {
  res.send('test');
});

// 登录
router.post('/login', function(req, res, next) {
  // 获取前端传过来的参数 post方式用req.Body形式获取参数
  var param = {
    userName:req.body.userName,
    userPwd:req.body.userPwd
  }
  User.findOne(param, function(err,doc) {
    if(err){
      res.json({
        status:"1",
        msg:err.message
      });
    }else{
        if(doc){
          res.cookie("userId",doc.userId,{ // 将用户信息存入cookie
            path:'/', // 存储路径
            maxAge: 1000*60*60 // 有效时间 单位毫秒
          }); 

          res.json({
            status:'0',
            msg:'',
            result:{
              userName:doc.userName
            }
          })
        }
    }
  });
  
});

module.exports = router;

NavHeader.vue 登录功能

<template>
      <header class="header">
        <symbol id="icon-cart" viewBox="0 0 38 32">
          <title>cart</title>
          <path class="path1" d="M37.759 0h-4.133c-0.733 0.004-1.337 0.549-1.434 1.255l-0.546 4.342c-0.081 0.484-0.496 0.849-0.997 0.849-0.005 0-0.009-0-0.014-0h-27.604c-0.003 0-0.007-0-0.011-0-1.674 0-3.031 1.357-3.031 3.031 0 0.34 0.056 0.666 0.159 0.971l2.52 8.062c0.385 1.194 1.486 2.043 2.785 2.043 0.126 0 0.25-0.008 0.372-0.023l22.983 0.002c0.515 0.131 0.626 0.768 0.626 1.283 0.005 0.044 0.009 0.095 0.009 0.146 0 0.501-0.294 0.933-0.718 1.134l-22.439 0.003c-0.354 0-0.642 0.287-0.642 0.642s0.287 0.642 0.642 0.642h22.745l0.131-0.071c0.919-0.392 1.551-1.287 1.551-2.33 0-0.058-0.002-0.116-0.006-0.173 0.021-0.108 0.033-0.24 0.033-0.376 0-1.072-0.732-1.973-1.724-2.23l-23.357-0.004c-0.063 0.008-0.135 0.013-0.209 0.013-0.719 0-1.332-0.455-1.566-1.093l-2.53-8.095c-0.048-0.154-0.076-0.332-0.076-0.515 0-0.973 0.782-1.764 1.752-1.778h27.657c1.159-0.004 2.112-0.883 2.232-2.011l0.547-4.345c0.010-0.083 0.078-0.147 0.161-0.152l4.133-0c0.354 0 0.642-0.287 0.642-0.642s-0.287-0.642-0.642-0.642z"></path>
          <path class="path2" d="M31.323 9.69c-0.022-0.003-0.048-0.004-0.074-0.004-0.328 0-0.598 0.248-0.633 0.567l-0.809 7.268c-0.003 0.022-0.004 0.048-0.004 0.074 0 0.328 0.248 0.598 0.567 0.633l0.074 0c0.001 0 0.003 0 0.004 0 0.327 0 0.596-0.246 0.632-0.563l0.809-7.268c0.003-0.022 0.004-0.048 0.004-0.074 0-0.328-0.248-0.598-0.567-0.633z"></path>
          <path class="path3" d="M27.514 25.594c-1.769 0-3.203 1.434-3.203 3.203s1.434 3.203 3.203 3.203c1.769 0 3.203-1.434 3.203-3.203s-1.434-3.203-3.203-3.203zM27.514 30.717c-1.060 0-1.92-0.86-1.92-1.92s0.86-1.92 1.92-1.92c1.060 0 1.92 0.86 1.92 1.92s-0.86 1.92-1.92 1.92z"></path>
          <path class="path4" d="M9.599 25.594c-1.769 0-3.203 1.434-3.203 3.203s1.434 3.203 3.203 3.203c1.769 0 3.203-1.434 3.203-3.203s-1.434-3.203-3.203-3.203zM9.599 30.717c-1.060 0-1.92-0.86-1.92-1.92s0.86-1.92 1.92-1.92c1.060 0 1.92 0.86 1.92 1.92s-0.86 1.92-1.92 1.92z"></path>
        </symbol>
        <div class="navbar">
          <div class="navbar-left-container">
            <a href="/">
              <img class="navbar-brand-logo" src="static/logo.png"></a>
          </div>
          <div class="navbar-right-container" style="display: flex;">
            <div class="navbar-menu-container">
              <!--<a href="/" class="navbar-link">我的账户</a>-->
              <span class="navbar-link"></span>
              <span v-text="nickName" v-if="nickName"></span>
              <a href="javascript:void(0)" class="navbar-link" @click="loginModalFlag=true" v-if="!nickName">Login</a>
              <a href="javascript:void(0)" class="navbar-link" v-if="nickName">Logout</a>
              <div class="navbar-cart-container">
                <span class="navbar-cart-count"></span>
                <a class="navbar-link navbar-cart-link" href="/#/cart">
                  <svg class="navbar-cart-logo">
                    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-cart"></use>
                  </svg>
                </a>
              </div>
            </div>
        <div class="md-modal modal-msg md-modal-transition" v-bind:class="{'md-show':loginModalFlag}">
          <div class="md-modal-inner">
            <div class="md-top">
              <div class="md-title">Login in</div>
              <button class="md-close" @click="loginModalFlag=false">Close</button>
            </div>
            <div class="md-content">
              <div class="confirm-tips">
                <div class="error-wrap">
                  <span class="error error-show" v-show="errorTip">用户名或者密码错误</span>
                </div>
                <ul>
                  <li class="regi_form_input">
                    <i class="icon IconPeople"></i>
                    <input type="text" tabindex="1" name="loginname" v-model="userName" class="regi_login_input regi_login_input_left" placeholder="User Name" data-type="loginname">
                  </li>
                  <li class="regi_form_input noMargin">
                    <i class="icon IconPwd"></i>
                    <input type="password" tabindex="2"  name="password" v-model="userPwd" class="regi_login_input regi_login_input_left login-input-no input_text" placeholder="Password" @keyup.enter="login">
                  </li>
                </ul>
              </div>
              <div class="login-wrap">
                <a href="javascript:;" class="btn-login" @click="login">登  录</a>
              </div>
            </div>
          </div>
        </div>
        <div class="md-overlay" v-if="loginModalFlag" @click="loginModalFlag=false"></div>
          </div>
        </div>
      </header>
</template>
<script>
import './../assets/css/login.css'
import axios from 'axios'
export default {
        data(){
            return{
              userName:'admin', // 用户名
              userPwd:'123456', // 密码
              errorTip:false, // 校验
              loginModalFlag:false, // 是否显示遮罩层
              nickName:''
            }
        },
        methods: {
          login(){ // 登录方法
              if(!this.userName || !this.userPwd){
                this.errorTip = true;
                return;
              }
              axios.post("/users/login",{
                userName:this.userName,
                userPwd:this.userPwd
              }).then((response)=>{
                let res = response.data;
                if(res.status=='0'){
                  this.errorTip = false;
                  this.loginModalFlag = false;
                  this.nickName = res.result.userName;
                }else{
                  this.errorTip = true;
                }
              })
          }
        }
}
</script>

node登出功能 

router/user.js

// 登出接口
router.post("/logout", function (req,res,next) {
  res.cookie("userId", "", { // 登出将userId设置为""
    path:"/",
    maxAge:-1 // 设置位过期
  })
  res.json({
    status:"0",
    msg:'',
    result:''
  })
})

登出vue前端

        logOut(){
            axios.post("/users/logout").then((response)=>{
              let res = response.data;
              if(res.status=="0"){
                this.nickName = '';
              }
            })
          }

》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

登录拦截

在app.js路由之前添加登录拦截

在express框架中只有安装了express-session框架session才可以使用

https://www.npmjs.com/package/express-session

安装 npm install express-session

node express  app.js   全局登录拦截

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var ejs = require('ejs');
/** 加载index路由模块 */
var index = require('./routes/index');
/** 加载user路由模块 */
var users = require('./routes/users');
/** 加载商品路由 */
var goods = require('./routes/goods')

var app = express();

// view engine setup
/** 设置访问的目录 设置views页面在哪放着 */
app.set('views', path.join(__dirname, 'views'));

/** 设置引擎是jade引擎 */
app.engine('.html',ejs.__express)
app.set('view engine', 'html');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
/** 安装第三方插件 */
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
/** 设置静态文件目录 path.join方法就是把两个变量连接要一块 __dirnam就是获取当前目录 */
app.use(express.static(path.join(__dirname, 'public')));

/**=== 全局登录拦截 ========================================================================================================= */
app.use(function (req,res,next) {
  if(req.cookies.userId){ // 如果登录成功进行下一步
    next();
  }else{
      console.log(`path:${req.path},originalUrl:${req.originalUrl}`);
          // req.originalUrl 获取请求路径  req.path 获取请求路径而不考虑参数
      if(req.originalUrl=='/users/login' || req.originalUrl=='/users/logout' || req.originalUrl.indexOf('/goods/list')>-1 ){
          next();
      }else{
          // req.originalUrl获取请求路径 如果是登录登出,则不拦截  否则就没法玩了
          // 如果未登录访问商品列表也放行
          res.json({  // 如果未登录访问其他功能则拦截
            status:'10001',
            msg:'当前未登录',
            result:''
          });
      }
  }
});
/**=== 全局登录拦截end ========================================================================================================= */

/** 表示当我们访问/的时候就去加载index的路由 */
app.use('/', index);
/** 当访问/user的时候,就去访问users的路由 */
app.use('/users', users);
/** 这通过不同的模块和访问地址来加以区分, 这样的化业务模块会做的更加细分 */
app.use('/goods', goods);

// catch 404 and forward to error handler
/** 全局对404的拦截 */
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err); // 如果next拿不到参数它就会用err这个参数,如果拿到的话它就不会用
});

// error handler
/** 对error的处理 */
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error'); // 一旦报错以后就会渲染这个error的页面
});

module.exports = app;

node express router/users.js 登录、登出、校验用户信息

var express = require('express');
var router = express.Router();

var User = require('./../models/user');

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

router.get('/test', function(req, res, next) {
  res.send('test');
});

// 登录
router.post('/login', function(req, res, next) {
  // 获取前端传过来的参数 post方式用req.Body形式获取参数
  var param = {
    userName:req.body.userName,
    userPwd:req.body.userPwd
  }
  User.findOne(param, function(err,doc) {
    if(err){
      res.json({
        status:"1",
        msg:err.message
      });
    }else{
        if(doc){
          res.cookie("userId",doc.userId,{ // 将用户信息存入cookie
            path:'/',
            maxAge: 1000*60*60
          }); 
          res.cookie("userName",doc.userName, {
            path:'/',
            maxAge: 1000*60*60
          });
          // req.session.user = doc; // 将用户信息存入session
          res.json({
            status:'0',
            msg:'',
            result:{
              userName:doc.userName
            }
          })
        }
    }
  });
});

// 登出接口
router.post("/logout", function (req,res,next) {
  res.cookie("userId", "", { // 登出将userId设置为""
    path:"/",
    maxAge:-1 // 设置位过期
  })
  res.json({
    status:"0",
    msg:'',
    result:''
  })
})

// 校验用户信息
router.get("/checkLogin", function (req,res,next) {
    if(req.cookies.userId){
      res.json({
        status:'0',
        msg:'',
        result: req.cookies.userName || '' // 获取cookeie req.cookies.属性
      });
    }else{ // 取不到就说明当前没有登录
      res.json({
        status:'1',
        msg:'未登录',
        result:''
      });
    }
})

module.exports = router;

vue 登录登出用户信息校验

<template>
      <header class="header">
        <symbol id="icon-cart" viewBox="0 0 38 32">
          <title>cart</title>
          <path class="path1" d="M37.759 0h-4.133c-0.733 0.004-1.337 0.549-1.434 1.255l-0.546 4.342c-0.081 0.484-0.496 0.849-0.997 0.849-0.005 0-0.009-0-0.014-0h-27.604c-0.003 0-0.007-0-0.011-0-1.674 0-3.031 1.357-3.031 3.031 0 0.34 0.056 0.666 0.159 0.971l2.52 8.062c0.385 1.194 1.486 2.043 2.785 2.043 0.126 0 0.25-0.008 0.372-0.023l22.983 0.002c0.515 0.131 0.626 0.768 0.626 1.283 0.005 0.044 0.009 0.095 0.009 0.146 0 0.501-0.294 0.933-0.718 1.134l-22.439 0.003c-0.354 0-0.642 0.287-0.642 0.642s0.287 0.642 0.642 0.642h22.745l0.131-0.071c0.919-0.392 1.551-1.287 1.551-2.33 0-0.058-0.002-0.116-0.006-0.173 0.021-0.108 0.033-0.24 0.033-0.376 0-1.072-0.732-1.973-1.724-2.23l-23.357-0.004c-0.063 0.008-0.135 0.013-0.209 0.013-0.719 0-1.332-0.455-1.566-1.093l-2.53-8.095c-0.048-0.154-0.076-0.332-0.076-0.515 0-0.973 0.782-1.764 1.752-1.778h27.657c1.159-0.004 2.112-0.883 2.232-2.011l0.547-4.345c0.010-0.083 0.078-0.147 0.161-0.152l4.133-0c0.354 0 0.642-0.287 0.642-0.642s-0.287-0.642-0.642-0.642z"></path>
          <path class="path2" d="M31.323 9.69c-0.022-0.003-0.048-0.004-0.074-0.004-0.328 0-0.598 0.248-0.633 0.567l-0.809 7.268c-0.003 0.022-0.004 0.048-0.004 0.074 0 0.328 0.248 0.598 0.567 0.633l0.074 0c0.001 0 0.003 0 0.004 0 0.327 0 0.596-0.246 0.632-0.563l0.809-7.268c0.003-0.022 0.004-0.048 0.004-0.074 0-0.328-0.248-0.598-0.567-0.633z"></path>
          <path class="path3" d="M27.514 25.594c-1.769 0-3.203 1.434-3.203 3.203s1.434 3.203 3.203 3.203c1.769 0 3.203-1.434 3.203-3.203s-1.434-3.203-3.203-3.203zM27.514 30.717c-1.060 0-1.92-0.86-1.92-1.92s0.86-1.92 1.92-1.92c1.060 0 1.92 0.86 1.92 1.92s-0.86 1.92-1.92 1.92z"></path>
          <path class="path4" d="M9.599 25.594c-1.769 0-3.203 1.434-3.203 3.203s1.434 3.203 3.203 3.203c1.769 0 3.203-1.434 3.203-3.203s-1.434-3.203-3.203-3.203zM9.599 30.717c-1.060 0-1.92-0.86-1.92-1.92s0.86-1.92 1.92-1.92c1.060 0 1.92 0.86 1.92 1.92s-0.86 1.92-1.92 1.92z"></path>
        </symbol>
        <div class="navbar">
          <div class="navbar-left-container">
            <a href="/">
              <img class="navbar-brand-logo" src="static/logo.png"></a>
          </div>
          <div class="navbar-right-container" style="display: flex;">
            <div class="navbar-menu-container">
              <!--<a href="/" class="navbar-link">我的账户</a>-->
              <span class="navbar-link"></span>
              <span v-text="nickName" v-if="nickName"></span>
              <a href="javascript:void(0)" class="navbar-link" @click="loginModalFlag=true" v-if="!nickName">Login</a>
              <a href="javascript:void(0)" class="navbar-link" @click="logOut" v-if="nickName">Logout</a>
              <div class="navbar-cart-container">
                <span class="navbar-cart-count"></span>
                <a class="navbar-link navbar-cart-link" href="/#/cart">
                  <svg class="navbar-cart-logo">
                    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-cart"></use>
                  </svg>
                </a>
              </div>
            </div>
        <div class="md-modal modal-msg md-modal-transition" v-bind:class="{'md-show':loginModalFlag}">
          <div class="md-modal-inner">
            <div class="md-top">
              <div class="md-title">Login in</div>
              <button class="md-close" @click="loginModalFlag=false">Close</button>
            </div>
            <div class="md-content">
              <div class="confirm-tips">
                <div class="error-wrap">
                  <span class="error error-show" v-show="errorTip">用户名或者密码错误</span>
                </div>
                <ul>
                  <li class="regi_form_input">
                    <i class="icon IconPeople"></i>
                    <input type="text" tabindex="1" name="loginname" v-model="userName" class="regi_login_input regi_login_input_left" placeholder="User Name" data-type="loginname">
                  </li>
                  <li class="regi_form_input noMargin">
                    <i class="icon IconPwd"></i>
                    <input type="password" tabindex="2"  name="password" v-model="userPwd" class="regi_login_input regi_login_input_left login-input-no input_text" placeholder="Password" @keyup.enter="login">
                  </li>
                </ul>
              </div>
              <div class="login-wrap">
                <a href="javascript:;" class="btn-login" @click="login">登  录</a>
              </div>
            </div>
          </div>
        </div>
        <div class="md-overlay" v-if="loginModalFlag" @click="loginModalFlag=false"></div>
          </div>
        </div>
      </header>
</template>
<script>
import './../assets/css/login.css'
import axios from 'axios'
export default {
        data(){
            return{
              userName:'admin', // 用户名
              userPwd:'123456', // 密码
              errorTip:false, // 校验
              loginModalFlag:false, // 是否显示遮罩层
              nickName:''
            }
        },
        mounted() {
          this.checkLogin();
        },
        methods: {
          checkLogin(){
              axios.get("/users/checkLogin").then((response)=>{
                  let res = response.data;
                  console.log(res);
                  if(res.status=="0"){
                    this.nickName = res.result;
                  }
              });
          },
          login(){ // 登录方法
              if(!this.userName || !this.userPwd){
                this.errorTip = true;
                return;
              }
              axios.post("/users/login",{
                userName:this.userName,
                userPwd:this.userPwd
              }).then((response)=>{
                let res = response.data;
                if(res.status=='0'){
                  this.errorTip = false;
                  this.loginModalFlag = false;
                  this.nickName = res.result.userName;
                }else{
                  this.errorTip = true;
                }
              });
          },
          logOut(){
            axios.post("/users/logout").then((response)=>{
              let res = response.data;
              if(res.status=="0"){
                this.nickName = '';
              }
            })
          }
        }
}
</script>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值