当前位置:网站首页>05 | 后台登录:基于账号密码的登录方式(下)
05 | 后台登录:基于账号密码的登录方式(下)
2022-07-30 12:57:00 【程序员很菜】
你好, 我是程序猿零壹。
在上一篇中,我们一起制作了登录页面,并使用ajax进行数据提交,那提交过来的参数应该怎么接受、处理呢。
Route::get('/login', 'Admin\[email protected]');
Route::post('/login', 'Admin\[email protected]');在routes/web.php文件中,我们定义了上面两条路由。第一条是get方式,用来展示登录页面;第二条是post方式,用来接收用户提交过来的数据。
编辑app/Http/Controllers/Admin/AuthController.php,添加loginPost方方法,内容如下:
<?php
namespace App\Http\Controllers\Admin;
use App\Services\Admin\AuthService;
class AuthController extends BaseController
{
private $authService;
public function __construct(AuthService $authService)
{
$this->authService = $authService;
}
public function login(){
return $this->view('admin/auth/login');
}
public function loginPost(){
$params = [
'username' => request()->input('username',''),
'password' => request()->input('password',''),
];
$response = $this->authService->login($params);
return $response;
}
}这里我们引入了app/Services/AuthService.php这个业务文件,专门用来处理相对应的业务逻辑。AuthService文件的内容如下:
<?php
namespace App\Services\Admin;
use App\Tools\Response\JsonResponse;
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2022/7/26
* Time: 20:40
*/
class AuthService
{
public function login($params){
return JsonResponse::success();
}
}现在login函数只有一行代码,用来返回一个json数据给前端页面,以后所有的接口请求,我们都会使用这样的方式来返回数据。新建app/Tools/Resonse/JsonResponse.php文件,内容如下:
<?php
namespace App\Tools\Response;
use App\Constants\ResponseCode;
class JsonResponse
{
public static function success($data=[],$msg = '操作成功'){
return response()->json(['code'=> ResponseCode::SUCCESS,'msg'=>$msg,'data'=>$data])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
public static function fail($msg = ''){
return response()->json(['code'=> ResponseCode::FAIL,'msg'=>$msg])->setEncodingOptions(JSON_UNESCAPED_UNICODE);
}
}新建app/Constants/ResponseCode.php,内容如下:
<?php
declare(strict_types=1);
namespace App\Constants;
class ResponseCode
{
const SUCCESS = 'success';
const FAIL = 'fail';
const ADMIN_LOGOUT = 'admin_logout';
}到这里,当我们点击登录页面的提交按钮后,会登录成功并跳转到/admin/home/index这个页面,也就是后台首页。
但是上面的步骤中,我们并没有对账号密码进行校验。现在我们就要添加这一步骤了。在这之前,我们先来了解下在laravel框架中,如何与数据库进行交互。
在laravel中,给我们提供一个强大的工具来与数据库进行交互,这就是ORM。每个数据库表都有一个对应的ORM模型用来与之交互,可以通过模型来查询数据库中的数据,以及在数据表中插入和更新数据。
在开始使用ORM之前,我们需要修改.env文件并配置其中跟数据库有关的配置。


配置完上图的数据库配置之后,我们就可以使用ORM与数据库交互了。
不过在这之前,我们需要先完成数据库表的创建。我们需要两张表,一张表取名为accounts,用来存储账号基本信息,例如昵称,头像,性别等信息;另外一张表取名为account_password,用来存储账号密码等信息。创建及插入数据的sql语句如下:
CREATE TABLE `accounts` (
`account_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`nickname` VARCHAR(50) NOT NULL COMMENT '昵称' COLLATE 'utf8mb4_general_ci',
`avatar` VARCHAR(255) NOT NULL COMMENT '头像' COLLATE 'utf8mb4_general_ci',
`sex` TINYINT(3) NOT NULL DEFAULT '3' COMMENT '性别 1-男 2-女 3-未知',
`status` TINYINT(3) NOT NULL DEFAULT '1' COMMENT '状态 1-启用 2-禁用',
`created_at` INT(10) NOT NULL DEFAULT '0',
`updated_at` INT(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`account_id`) USING BTREE
)
COMMENT='账号表'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
INSERT INTO `accounts` (`account_id`, `nickname`, `avatar`, `sex`, `status`, `created_at`, `updated_at`) VALUES
(1, '零壹', '/static/admin/imgs/avatar.jpg', 3, 1, 1653533903, 1653533903);
CREATE TABLE `account_password` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`account_id` INT(10) NOT NULL DEFAULT '0',
`name` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci',
`passwd` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci',
`salt` CHAR(6) NOT NULL DEFAULT '' COLLATE 'utf8mb4_general_ci',
`created_at` INT(10) NOT NULL DEFAULT '0',
`updated_at` INT(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `name` (`name`) USING BTREE,
INDEX `account_id` (`account_id`) USING BTREE
)
COMMENT='账号密码'
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
INSERT INTO `account_password` (`id`, `account_id`, `name`, `passwd`, `salt`, `created_at`, `updated_at`) VALUES
(1, 1, 'admin', 'b3de394180907ace8d94611486b0d9aab5f110a8dbda1b28a83277117fa89b30', 'prz6g9', 1653533903, 1653533903);数据库表现在已经创建好并插入了测试数据
账号:admin 密码:123456
画外音:这个密码简直不要太简单,正式环境建议设置为复杂密码。
接下来我们来创建ORM模型文件。
新建app/Models/BaseModel.php文件,内容如下:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
public $casts = [];
public $guarded=[];
public $dateFormat = 'U';
public $timestamps = true;
}新建app/Models/AccountModel.php文件,内容如下:
<?php
namespace App\Models;
class AccountModel extends BaseModel
{
public $table = 'accounts';
public $primaryKey = 'account_id';
}新建app/Models/AccountPasswordModel.php文件,内容如下:
<?php
namespace App\Models;
class AccountPasswordModel extends BaseModel
{
public $table = 'account_password';
public $primaryKey = 'id';
}好了,现在ORM模型文件都已经创建完毕了。那要怎么使用呢?我们接着往下看。
新建app/Tools/Common/AuthTool.php,内容如下:
<?php
namespace App\Tools\Common;
class AuthTool
{
public static function generateSalt($saltLength=6){
$str = '23456789abcdefghijkmnpqrstuvwxyz';
$length = strlen($str);
$str = str_split($str);
$lastPosition = $length-1;
$salt = '';
for($i=0;$i<$saltLength;$i++) {
$rand = rand(0, $lastPosition);
$salt .= $str[$rand] ?? 'a';
}
return $salt;
}
public static function encryptPassword($pwd, $salt=''){
$password = hash('sha256',md5($pwd).$salt);
return $password;
}
}修改app/Services/AuthService.php的login函数,内容如下:
<?php
namespace App\Services\Admin;
use App\Models\AccountModel;
use App\Models\AccountPasswordModel;
use App\Tools\Common\AuthTool;
use App\Tools\Response\JsonResponse;
class AuthService
{
public function login($params){
if(empty($params['username']) || empty($params['password'])) {
return JsonResponse::fail('登录失败,账号不存在或者密码错误');
}
$accountPassword = AccountPasswordModel::query()
->select(['name','passwd','salt','account_id'])
->where(['name'=>$params['username']])
->first();
if(empty($accountPassword)) {
return JsonResponse::fail('登录失败,账号不存在或者密码错误');
}
$encryptPassword = AuthTool::encryptPassword($params['password'], $accountPassword['salt']);
if($encryptPassword != $accountPassword['passwd']) {
return JsonResponse::fail('登录失败,账号不存在或者密码错误');
}
$account = AccountModel::query()
->select(['account_id'])
->where(['account_id'=>$accountPassword['account_id']])
->first();
if(empty($account)) {
return JsonResponse::fail('登录失败,账号不存在或者密码错误');
}
request()->session()->put('admin_login_user_id',$account['account_id']);
return JsonResponse::success();
}
}下面,我们对login这个函数来做一个拆解说明。
$accountPassword = AccountPasswordModel::query()
->select(['name','passwd','salt','account_id'])
->where(['name'=>$params['username']])
->first();上面语句使用的是连贯操作,从account_password表查询一条name为admin的记录,相当于mysql语句:
select name,passwd,salt,account_id from account_password where name='admin' limit 1;
如果没有查找到记录,说明账号不存在,返回错误提示;如果查找到记录,说明账号存在,获取到$accountPassword ,需要进行密码校验。
将用户提交的密码123456使用AuthTool的encryptPassword函数进行加密后得到$encryptPassword变量,将$encryptPassword 与 $accountPassword['passwd']进行对比,如果相同,则表示密码校验通过;如果不同,则表示密码校验不通过,返回错误提示。
然后根据$accountPassword['account_id']到account表查找对应账号信息。
如果账号信息存在,则登录成功,否则返回错误提示。
// select account_id,name,avatar from accounts where account_id = 1 limit 1;
$account = AccountModel::query()
->select(['account_id','nickname','avatar'])
->where(['account_id'=>$accountPassword['account_id']])
->first();将下来,我们需要将账号信息保存到session,并返回操作成功给前端页面,前端接收到后端返回的数据后,判断登录成功,将跳转到后台首页,否则弹窗提示错误信息。到此,登录操作完成。
request()->session()->put('admin_login_user_id',$account['account_id']);session,也叫会话控制,用来存储特定用户会话所需要的属性及配置信息。当用户在不同的页面跳转的时候,存储在session对象中的变量或者数据将不会丢失,而是在整个会话中一直存在下去。有关session的详细信息,请自行百度查阅,或者在关注公众号菜单回复session,即可查看相关文章。
今天我们一起完成了整个登录操作,有点意犹未尽的感觉。下一篇我们将来创建一个带有头部和左侧菜单栏的公共页面。
敬请期待!
欢迎关注
最后,欢迎大家关注我的公众号呀 。打开微信搜索程序猿零壹公众号即可关注,希望能与大家共同进步。
边栏推荐
- CV-Model【2】:MobileNet v1
- 一文读懂Elephant Swap,为何为ePLATO带来如此高的溢价?
- 434. 字符串中的单词数
- R语言筛选时间序列数据的子集(subset time series data)、使用window函数筛选连续日期时间范围内的数据(start参数和end参数分别指定起始和结束时间)
- 基于DoS攻击能量分级的ICPS综合安全控制与通信协同设计
- How to display an Excel table in the body of an email?
- 12、 学习MySQL 排序
- R语言ggplot2可视化:使用ggpubr包的ggmaplot函数可视化MA图(MA-plot)、设置label.select参数自定义在图中显示标签的基因类型(自定义显示的标签列表)
- Dry Goods Sharing: Various Implementation Methods of Bean Management Factory with Great Use of Small Skills
- 每天学一点Scala之 伴生类和伴生对象
猜你喜欢

【河北工业大学】考研初试复试资料分享

SyntaxError: EOL while scanning string literal

TaskDispatcher源码解析

Raja Koduri澄清Arc GPU跳票传闻 AXG年底前新推四条产品线

MySQL查询性能优化

【记一个kaggle划水比赛】PetFinder.my - Pawpularity Contest 宠物预测

DeFi 巨头进军 NFT 领域 用户怎么看?

js 构造函数 return 非空对象,其实例化的对象在原型上的差异

Beijing, Shanghai and Guangzhou offline events丨The most unmissable technology gatherings at the end of the year are all gathered

如何判断自己是否适合IT行业?方法很简单
随机推荐
正确处理页面控制器woopagecontroller.php,当提交表单时是否跳转正确的页面
腾讯称电竞人才缺口200万;华为鸿蒙3.0正式发布;乐视推行每周工作4天半?...丨黑马头条...
R语言筛选时间序列数据的子集(subset time series data)、使用window函数筛选连续日期时间范围内的数据(start参数和end参数分别指定起始和结束时间)
元宇宙的六大支撑技术
R语言使用aov函数进行单因素协方差分析(One-way ANCOVA)、使用effects包中的effect函数来计算调整后的分组均值(calculate adjusted means)
基于反步积分滑模摩擦补偿的光电伺服转台控制
JS事件的相关特性以及原理
R语言时间序列数据算术运算:使用log函数将时间序列数据的数值对数化(平方、开平方、指数化等函数类似使用)
第十三天笔记
Hand tearing read-write lock performance test
在 Scala 中读取整个文件
C#实现软键盘的制作
el-table中el-table-column下的操作切换class样式
【软考软件评测师】基于规则说明的测试技术上篇
js 构造函数 return 非空对象,其实例化的对象在原型上的差异
剑指 Offer 05. 替换空格
【23考研】408代码题参考模板——链表
MySQL查询性能优化
datax enables hana support and dolphinscheduler enables datax tasks
机器学习——特征选择