Appearance
模拟用户数据
/Users/luxiaoqing/project/api-test/cp/database/seeders/DatabaseSeeder.php
User::factory(10)->create();
$user = User::find(1);
$user->email = 'aaaa@qq.com';
$user->name = '超级管理员';
$user->save();php
userFactory
password =>Hask::make('admin88')单个 php artisan db:seed --class=TopicsTableSeeder
php artisan migrate:refresh --seed/Users/luxiaoqing/project/api-test/cp/database/factories/UserFactory.php
工程制造模拟数据
api工具加入提起token操作

后置操作->变量名称(token) ->$.data.token
根目录-> auth->Bearer Token->
任务2 api 登录接口
任务一:用户登录控制器和API #1、创建登录控制器
php artisan make:controller LoginController#2、设置登录API #3、设置Controller基类成功返回信息的统一格式:
protected function success($message='',$data=[],$code=0){
return response()->json([
'code'=>$code,
'status'=>'success',
'message'=>$message,
'data'=>$data
]);
}#4、生成token并返回token
#5、开启sanctume鉴权服务提供者:
/Users/luxiaoqing/project/api-test/cp/app/Http/Kernel.php
kernel文件中,api组:
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 开启
#6、api工具验证接口
Route::post('login',\App\Http\Controllers\LoginController::class);php
class LoginController extends Controller
{
//
public function __invoke(Request $request)
{
$request->validate([
'email'=>['required','email'],
'password' =>['required','min:3']
]);
$user = User::whereEmail($request->email)->first();
if($user && Hash::check($request->password,$user->password)) {
$token = $user->createToken('token')->plainTextToken;
return $this->success('成功',[
'token'=>$token,
'user'=>$user
]);
}
return $this->success(ValidationException::withMessages(['password'=>'密码错误'])->getMessage(),[],0);
}
}任务三:Request验证和响应Response #1、创建LoginRequest验证并设置。
php artisan make:request LoginRequestphp
class LoginRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'email'=>['required','email'],
'password' =>['required','min:3']
];
}
}ps : laravel 做表单验证失败后返回到首页的问题
http 请求头加上 Accept application/json
#2、创建UserResource并演示。
php artisan make:resource UserResourcephp
class UserResource extends JsonResource
{
public function toArray(Request $request): array
{
return ['city' => 'beijing'] + parent::toArray($request); //array_merge(arr1,arr2)
}
}['city' => 'beijing'] + parent::toArray($request); 作用是前面覆盖后面 array_merge(arr1,arr2) 后面覆盖前面
return $this->success('成功',[
'token'=>$token,
'user'=> new UserResource($user)
]);user": {
"city": "beijing", // resource 添加的属性
"id": 1,
"name": "超级管理员",
...,
}任务4:创建用户注册控制和API #1、创建用户注册控制RegisterController
php
// RegisterRequest
public function rules(): array
{
return [
'email'=>['required','email'],
'password' =>['required','min:3','confirmed']
];
}confirmed 需要在接口传 password_confirmation的字段(能修改吗?)
php
class RegisterController extends Controller
{
public function __invoke(RegisterRequest $request,User $user)
{
$data = ['password' => Hash::make($request->password)] + $request->input();
$user->fill($data)->save();
return $this->success('成功',['user'=>$user->refresh()]);
}
}#2、实现注册接口
任务5:邮件验证码服务 #1、创建服务CodeService并声明
class AppServiceProvider extends ServiceProvider
{
public function register(): void{
$this->app->instance(CodeService::class,new CodeService()); //产生一个实例
// $this->app->bind() //调用一次产生一个实例
}
public function boot(): void{}
}namespace App\Services;
class CodeService {
public function send() {
return '000';
}
}//调用实例方法
Route::get('send/register/code', function () {
return app(CodeService::class)->send();
});Route::get('/', function () {
$user = User::factory()->make();
return (new ValidateEmailCodeNotification())->toMail($user);
});Ps : make 和 create的区别,make创建在内存不在表,create直接创建在表
#2、创建邮件验证码通知类,并设置邮件通知模板:(new ValidateEmailCodeNotifiaction(333333))->toMail($user); 设置邮件模板。
php artisan make:notification ValidateEmailCodeNotificationphp
class CodeService {
public function send($email) {
$user = User::factory()->make([
'email'=>$email
]);
if(Cache::get($email)) abort('403','验证码已发送');
Notification::send($user, new ValidateEmailCodeNotification($code = $this->getCode()));
Cache::put($email,$code,config('time.expire_time'),60);
return $code;
}
public function getCode(): int
{
return mt_rand(100000,999999);
}
public function check() {
}
}#3、发送邮件验证码,并缓存。
php
class CodeService {
public function send($email) {
// 发送邮件
$user= User::factory()->make([
'email'=>$email
]);
if(Cache::get($email)) abort(403, '验证码已发送'); // 打断
Notification::send($user, new ValidateEmailCodeNotification($code = $this->getCode()));
Cache::put($email,$code,config('time.expire_time'), 60); // config目录下的time文件下的expire_time
}
public function getCode() {
return mt_rand(100000,999999);
}
public function check($email,$code) {}
}Ps: 直接在代码调用 env('CACHE_EXPIRE_TIME'),能直接获取值,但不建议
因为在上线之前,需要打包构建,产生缓存,加快访问速度,env会被固定化,到时候访问不到
#4、config的使用
Cache::put($email,$code,config('time.expire_time'), 60);任务6:创建验证码服务器 #1、创建验证码服务器CodeController
public function registerCode(RegisterCodeRequest $request) {
$code = app(CodeService::class)->send($request->email);
return $this->success('发送成功',[
'code'=>$code
]);
}#2、env邮件地址设置 : MAIL_HOST=localhost #3、mailhog模拟的邮件提供商,端口号为:8025,homestead自带
RegisterCodeRequest
'email'=>['required','email',Rule::unique('users','email')]没成功,不在homestead环境
任务8:注册用户验证码认证 #1 添加code验证字段 #2 创建CodeRule验证规则,验证栏以new CodeRule形式调用。
php artisan make:rule CodeCheckRulephp
// request 直接调用
class CodeCheckRule implements Rule{
public function __construct(){}
public function passes($attribute, $value){ return Cache::get(request('email')) == $value; }
public function message() { return '验证码输入错误';}
}// 和视频不一样,mac
public function validate(string $attribute, mixed $value, Closure $fail): void
{
//
}php
// \cp\app\Http\Requests\RegisterRequest.php
public function rules(): array
{
return [
'email'=>['required','email'],
'password' =>['required','min:3'],
'code'=>['required',new CodeCheckRule()]
];
}#3 api工具演示
ps: 设置 编辑器 实时模版 设置快捷代码块
任务9:找回密码功能 #1 创建UserController --api,配置接口
php artisan make:controller UserController --api#2 创建artisan make:request UserFindPasswordRequest 验证 #3 创建找回密码邮件验证码功能 artisan make:request FindPasswordCodeRequest
php
UserFindPasswordRequest
public function rules(): array
{
return [
'email'=>['required','email',Rule::exists('users','email')],
'password'=>['required','confirmed','min:3'],
'code'=>['required',new CodeCheckRule()]
];
}Ps: rule 目前有unique 和 exists
php
public function findPassword(FindPasswordRequest $request) {
$user = User::whereEmail($request->email)->firstOrFail();
$user->password = Hash::make($request->password);
$user->save();
return $this->success('重置密码成功',[
'user'=>$user
]);
}任务10:用户的列表显示和单个用户信息查看
php aritisan make:controller UserController --api
// 查看全部路由
php artisan route:list
// 筛选
php artisan route:list | grey userRoute::apiResource('users',\App\Http\Controllers\UserController::class);php artisan route:list | grep users#1 用户列表的显示
php
public function __controller() {
$this->middleware(['auth:sanctum'])->only(['update','destory'])
}
public function index() {
return UserResource::collection(User::latest()->paginate())
}
//UserResource 的使用
return $this->success('登陆成功',[
'token'=>$user->createToken('token')->plainTextToken,
'user'=>new UserResource($user),//单个的使用
]);
// 列表的使用
UserResource::collection#2 单个用户信息查看
任务11:Policy管理用户操作的权限
#1 创建判定超管的全局函数
php
if(!function_exists('isSuperAdmin')) {
function isSuperAdmin() {
return Auth::user() && Auth::id() == 1;
}
}#2 生成UserPolicy
php artisan make:policy UserPolicy --model=Userphp
class UserPolicy
{
public function before(): bool
{
// true 下面不执行,false 后面不用看,完全没有权限,undefined是执行下面的方法
if(isSuperAdmin()) return true;
}
public function viewAny(User $user): bool
{
//
}
public function view(User $user, User $model): bool
{
//
}
public function create(User $user): bool
{
//
}
public function update(User $user, User $model): bool
{
//user(登录用户) model(模型用户,修改的数据)
return $user->id === $model->id;
}
public function delete(User $user, User $model): bool
{
}
public function restore(User $user, User $model): bool
{
//
}
public function forceDelete(User $user, User $model): bool
{
//
}
}php
class UserController extends Controller {
public function __construct() {
$this->middleware(['auth:sanctum'])->only(['update','destroy','getCurrentUserInfo','logout']);
}
//显示所有用户
public function index() {
return UserResource::collection(User::latest()->paginate());
}
//显示单用户信息
public function show(User $user) {
return $this->success(data:new UserResource($user));
}
//更新单用户信息
public function update(UpdateUserRequest $request,User $user) {
$this->authorize('update',$user);
$user->fill($request->input())->save();
return $this->success('用户信息更新成功',[
'user'=>$user
]);
}
//删除单用户信息
public function destroy(User $user) {
$this->authorize('delete',$user);
$user->delete();
return $this->success('删除成功');
}
//找回用户密码
public function findPassword(FindPasswordRequest $request) {
$user = User::whereEmail($request->email)->firstOrFail();
$user->password = Hash::make($request->password);
$user->save();
return $this->success('重置密码成功',[
'user'=>$user
]);
}
public function getCurrentUserInfo(){
return $this->success(data:new UserResource(Auth::user()));
}
public function logout(){
if($user = Auth::user()){
$user->tokens()->delete();
}
}
public function getOneTopics(Request $request){
$topics = Topic::with('user')
->when(request('u_id'),function($query){
return $query->where('user_id',request('u_id'));
})
->latest()
->paginate(5);
return TopicResource::collection($topics);
}
public function getOneComments(Request $request){
$comments = Comment::with('user')
->when(request('u_id'),function($query){
return $query->where('user_id',request('u_id'));
})
->latest()
->paginate(5);
return CommentResource::collection($comments);
}
}#3 在api 调试
