由于 layuiAdmin 接管了视图层,所以不必避免可能会与服务端分开部署,这时你有必要了解一下 layuiAdmin 默认提供的:从 登录 到 接口鉴权,再到 注销 的整个流程。
首先,把layuiAdmin的登录拦截打开。
打开 /public/static/src/config.js ,将
interceptor
参数设置为true。
当其未检查到
access_token
值时,会强制跳转到登录页面http://localhost/#/user/login
interceptor: true //true为开启,false为关闭 (是否开启未登入拦截)
打开登录对应的视图文件 /public/static/src/views/user/login.html,提供后端数据接口,返回 access_token 值。
layuiAdmin 会将服务端返回的 access_token 值进行本地存储。
<script type="text/html" template>
<link rel="stylesheet" href="{{ layui.setter.base }}style/login.css?v={{ layui.admin.v }}-1" media="all">
</script>
<div class="layadmin-user-login layadmin-user-display-show" id="LAY-user-login" style="display: none;">
<div class="layadmin-user-login-main">
<div class="layadmin-user-login-box layadmin-user-login-header">
<h2>XXX信息管理系统</h2>
<p>后台信息管理系统Vx.x</p>
</div>
<div class="layadmin-user-login-box layadmin-user-login-body layui-form">
<div class="layui-form-item">
<label class="layadmin-user-login-icon layui-icon layui-icon-username" for="username"></label>
<input type="text" name="username" id="username" lay-verify="required" placeholder="用户名" class="layui-input">
</div>
<div class="layui-form-item">
<label class="layadmin-user-login-icon layui-icon layui-icon-password" for="password"></label>
<input type="password" name="password" id="password" lay-verify="required" placeholder="密码" class="layui-input">
</div>
<div class="layui-form-item">
<button class="layui-btn layui-btn-fluid" id="submit" onclick="dologin()">登 录</button>
<div class="layui-form-mid layui-word-aux" style="float: right;">
<a href="javascript:;" onclick="pwdforget()" style="color: gray;">忘记密码</a>
</div>
</div>
</div>
</div>
</div>
<script>
layui.use(['admin', 'form', 'layer'], function () {
$ = layui.$
, setter = layui.setter
, admin = layui.admin
, form = layui.form
, router = layui.router()
, search = router.search;
$('#username').focus();//获取用户名焦点
layer.closeAll();
// 回车登录
$('input').keydown(function (e) {
if (e.keyCode == 13) {
if ($('.layui-layer-dialog').length == 0) {
dologin();
} else {
layer.closeAll();
}
}
});
});
function dologin() {
var username = $.trim($('#username').val());
var password = $.trim($('#password').val());
//var verifycode = $.trim($('#verifycode').val());本例登录不使用验证码。
if (username == '') {
layer.msg('请填写用户名', { offset: '15px', icon: 2, time: 1000 });
$("#username").focus();
return;
}
if (password == '') {
layer.msg('请输入密码', { offset: '15px', icon: 2, time: 1000 });
$("#password").focus();
return;
}
var _index = layer.load(2);//提交登录加载等待
// /login/login 为TP6接口,返回数据,此接口方式需要配置.htaccess
//详情查看https://blog.csdn.net/xych_ccui/article/details/129758177
$.post('/login/login', { 'username': username, 'password': password }, function (res) {
layer.close(_index);//服务器返回结果关闭加载等待,执行提示框。
if (res.code > 0 || res.code < 0) {
if (res.code < 0) {
$("#username").val(""); //清空文本框
$("#username").focus(); //用户名错误,光标返回给用户名
}
if (res.code > 0) {
$("#password").val(""); //清空文本框
$("#password").focus(); //密码错误,光标返回给密码。
}
layer.msg(res.msg, { offset: '15px', icon: 2, time: 1200 });
} else {
layer.close(_index);//关闭加载等待
layer.msg(res.msg, { icon: 1, time: 1300 }, function () {
//layui.data(setter.tableName, { 这是默认的,会永久存储在本地表中,除非物理删除。关闭页面后,登录不会失效。
layui.sessionData(setter.tableName,{//这里是新修改的,主要作用是临时存储本地表中,关闭页面后将失效。
key: setter.request.tokenName,
value: res.data.access_token
});
//layui.data(setter.tableName, {
layui.sessionData(setter.tableName, {
key: 'username',
value: res.data.username
})
//layui.data(setter.tableName, {
layui.sessionData(setter.tableName, {
key: 'uid',
value: res.data.uid
});
//这里的跳转,根据浏览器地址栏访问的地址,拦截后登录成功会跳转到之前输入的地址。
location.hash = search.redirect ? decodeURIComponent(search.redirect) : '/';
});
}
}, 'json')
}
// 忘记密码
function pwdforget() {
layer.msg('请联系网站技术重置密码。', { offset: '15px', icon: 2, time: 2000 });
}
</script>
本地存储是对 localStorage 和 sessionStorage 的友好封装,可更方便地管理本地数据。
localStorage 持久化存储:layui.data(table, settings),数据会永久存在,除非物理删除。
sessionStorage 会话性存储:layui.sessionData(table, settings),页面关闭后即失效。注:layui 2.2.5 新增。
使用layui.sessionData时,要修改配置文件。
/public/static/src/index.js/public/static/src/lib/view.js
///public/static/src/index.js
//强制拦截未登入
if(setter.interceptor){
var local = layui.data(setter.tableName);
if(!local[setter.request.tokenName]){
return location.hash = '/users/login/redirect='+ encodeURIComponent(pathURL); //跳转到登入页
}
}
//修改为如下
if(setter.interceptor){
var local = layui.sessionData(setter.tableName);
if(!local[setter.request.tokenName]){
return location.hash = '/users/login/redirect='+ encodeURIComponent(pathURL); //跳转到登入页
}
}
///public/static/src/lib/view.js
//清除 token,并跳转到登入页
view.exit = function(){
//清空本地记录的 token
layui.data(setter.tableName, {
key: setter.request.tokenName
,remove: true
});
//增加sessionData的清除
layui.sessionData(setter.tableName, {
key: setter.request.tokenName
,remove: true
});
//跳转到登入页
location.hash = '/users/login';
};
// .......
// .......
if(request.tokenName){
var sendData = typeof options.data === 'string'
? JSON.parse(options.data)
: options.data;
//自动给参数传入默认 token
options.data[request.tokenName] = request.tokenName in sendData
? options.data[request.tokenName]
: (layui.sessionData(setter.tableName)[request.tokenName] || '');
//: (layui.data(setter.tableName)[request.tokenName] || '');
//自动给 Request Headers 传入 token
options.headers[request.tokenName] = request.tokenName in options.headers
? options.headers[request.tokenName]
: (layui.sessionData(setter.tableName)[request.tokenName] || '');
//: (layui.data(setter.tableName)[request.tokenName] || '');
}
- TP6登录接口
- /app/controller/Login.php
/login/login 我用的TP6接口格式,返回数据,此接口格式需要配置.htaccess
详情查看https://blog.csdn.net/xych_ccui/article/details/129758177 学习笔记里关于.htaccess的配置
<?php
namespace app\controller;
use think\facade\Db;
use think\facade\Session;
use think\facade\View;
class Login
{
//登录验证
public function login()
{
$username = input('username');
$password = input('password');
$ret = Db::name('admin')
->where('username',$username)
->find();
if ($ret) {
if (md5($password) == $ret['password'] ) {
$access_token = md5($ret['username'] . $ret['password'] . 'LAYUIADMIN');
$res = array('uid'=>$ret['id'],'username'=>$ret['username'],'access_token'=>$access_token);
return json(['code'=>0,'msg'=>'登录成功','data'=>$res]);
}else {
return json (["code"=>1,"msg"=>'密码错误']);
}
}else {
return json (["code"=>-1,"msg"=>'用户名不存在']);
}
}
}
若鉴权成功,顺利返回数据;若鉴权失败,服务端的 code 应返回 1001(可在 config.js 自定义) , layuiAdmin 将会自动清空本地无效 token 并跳转到登入页。
- layuiAdmin的退出,已经配置好,修改一下TP6的实际接口就可以了。
- \public\static\src\controller\common.js
//退出
admin.events.logout = function () {
layer.confirm('确定要退出吗?', {
icon: 3,
btn: ['确定', '取消']
}, function () {
$.post('/login/logout', function (res) {
layer.msg(res.msg, { icon: 1, time: 1300 }, function () {
admin.exit();
});
}, 'json');
});
};
<?php
namespace app\controller;
use think\facade\Db;
use think\facade\Session;
use think\facade\View;
class Login
{
//退出
public function logout(){
$res = array('code'=>0,'msg'=>'退出成功','data'=>null);
return json ($res);
}
}