thinkphp5+phpjwt+vue 实现用户登录认证

后端

1、先安装phpjwt(需要composer安装)

composer require firebase/php-jwt

2、验证类

 $username,
            "iss"      => "",//签发组织
            "aud"      => "", //签发作者
            "iat"      => $time, //签发时间
            "nbf"      => $time, //生效时间
            "exp"      => $expire
        );
        $jwt    = JWT::encode($token, $key);
        return $jwt;
    }


    //校验jwt权限API
    public function verifyJwt($jwt)
    {
        $key = md5('nobita');
        try {
            $jwtAuth  = json_encode(JWT::decode($jwt, $key, array('HS256')));
            $authInfo = json_decode($jwtAuth, true);
            $msg      = [];
            if (!empty($authInfo['username'])) {
                $msg = [
                    'status'   => 0,
                    'msg'      => 'Token验证通过',
                    'username' => $authInfo['username']
                ];
            } else {
                //Token验证不通过,用户不存在
                $msg = [
                    'status' => 10001,
                    'msg'    => '当前用户不存在'
                ];
            }
            return json_encode($msg);
        } catch (\Firebase\JWT\SignatureInvalidException $e) {
            echo json_encode([
                'status' => 10002,
                'msg'    => 'Token无效'
            ]);
            exit;
        } catch (\Firebase\JWT\ExpiredException $e) {
            //Token过期
            echo json_encode([
                'status' => 10003,
                'msg'    => '登录信息已超时,请重新登录'
            ]);
            exit;
        } catch (Exception $e) {
            echo json_encode([
                'status' => 10004,
                'msg'    => '未知错误'
            ]);
            exit;
        }
    }
}

3、公共类统一验证

checkToken();
    }

    public function checkToken()
    {
        $header = Request::instance()->header();
        if (isset($header['authorization'])) {
            if ($header['authorization'] == 'null') {
                echo json_encode([
                    'status' => 10005,
                    'msg'    => 'Token不存在,拒绝访问'
                ]);
                exit;
            } else {
                $token         = new Jwttoken;
                $checkJwtToken = $token->verifyJwt($header['authorization']);
                //验证通过
                if (json_decode($checkJwtToken, true)['status'] == 0) {
                    //验证成功之后 继承了公共类的所有方法都可以直接调用登录用户 不用额外传参
                    $this->username = json_decode($checkJwtToken, true)['username'];
                    return true;
                }
            }
        } else {
            //Token不存在,拒绝访问
            return json_encode([
                'status' => 10006,
                'msg'    => '请勿非法登录'
            ]);
            exit;
        }

    }
}

4、登录控制器(登录控制器不用继承公共类,登录成功之后把生成的token返回给前端)

isPost()) {
            $data  = input();
            $isset = db('user')->where('username', $data['username'])->find();
            if (!$isset) {
                return json(['error' => '1000', 'errormsg' => '当前用户不存在']);
            }
            if (md5($data['password']) != $isset['password']) {
                return json(['error' => '1000', 'errormsg' => '密码错误']);
            } else {
                $token      = new Jwttoken();
                $user_token = $token->createJwt($isset['username']);
                return json(['error' => '0', 'errormsg' => '登录成功', 'token' => $user_token]);
            }
        }
    }

}

前端(vue+element)

1、登录操作(登录成功之后把token存入localStorage)

loginSubmit() {
  this.$refs['loginForm'].validate(async valid => {
    if (valid) {
      const {
        data: result
      } = await this.$http.post("/index/login/login", this.loginForm)
      if (result.error != 0) {
        this.$message.error(result.errormsg)
        return false;
      } else {
        this.$message.success(result.errormsg)
        window.localStorage.setItem('token', result.token);
        this.getuserinfo()
        this.gettypelist()
        this.getbooklist(0)
        this.logindialog = false
        this.loginForm = {
          username: '',
          password: '',
        }
      }
    } else {
      return false;
    }
  });
}

2、在main.js设置请求拦截器和响应拦截器

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

import axios from 'axios'

Vue.config.productionTip = false
Vue.use(ElementUI);
Vue.prototype.$http = axios
//配置请求根路径
axios.defaults.baseURL = 'http://www.shifuchen.top'

//请求拦截器
axios.interceptors.request.use(config => {
  config.headers.Authorization = window.localStorage.getItem('token')
  return config
}, error => {
  Promise.reject(error)
})
// 添加响应拦截器
axios.interceptors.response.use(response => {
  const status = response.data.status
  const msg = response.data.msg
  if (status > 10000) {
    ElementUI.Message({
      message: msg,
      type: 'error'
    });
    window.localStorage.clear();
    return false;
  } else {
    return response
  }
}, error => {
  Promise.reject(error)
});

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

3、在路由中挂载路由守卫router/index.js(判断token过期或者不合法直接跳转到登录页面)

//挂载路由导航守卫
router.beforeEach((to, from, next) => {
  //to将要访问的路径
  //from从哪个路径跳转而来
  //next放心函数 next()直接放行 next('/login')强制访问
  if (to.path === '/login') return next();
  //获取token
  const tokenStr = window.localStorage.getItem('token');
  if (!tokenStr) return next('/login')
  next()
})

 

你可能感兴趣的:(vue,php,js)