请求指导基于Laravel开发POST型PHP认证API(返回JSON)
如何用Laravel开发支持密码/SSO双认证的POST JSON API
没问题,我来一步步教你实现这个需求——用Laravel框架开发一个基于POST请求的API,支持邮箱+密码和SSO token两种验证方式,并且返回你指定格式的JSON响应。
1. 前期准备:模型与迁移
首先确保你已经创建了Laravel项目(如果没有,用composer create-project laravel/laravel auth-api快速生成)。我们需要调整用户表的字段,匹配你的需求:
创建用户表迁移(如果是新项目,修改默认的users迁移)
打开database/migrations/xxxx_xx_xx_xxxxxx_create_users_table.php,修改up()方法:
public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('email_address')->unique(); // 用email_address代替默认email $table->string('password')->nullable(); // SSO用户可能不需要密码,设为nullable $table->timestamp('last_login')->nullable(); $table->timestamps(); }); }
然后运行迁移:php artisan migrate
配置User模型
打开app/Models/User.php,更新$fillable和认证字段:
namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use Notifiable; // 允许批量赋值的字段 protected $fillable = [ 'email_address', 'password', 'last_login', ]; // 指定认证用的邮箱字段(默认是email,这里改成email_address) public function getAuthIdentifierName() { return 'email_address'; } // 隐藏敏感字段(比如密码哈希) protected $hidden = [ 'password', 'remember_token', ]; }
2. 配置API路由
打开routes/api.php,添加POST登录路由:
use App\Http\Controllers\AuthController; Route::post('/auth/login', [AuthController::class, 'login'])->name('api.auth.login');
因为API接口不需要CSRF保护,所以需要在app/Http/Middleware/VerifyCsrfToken.php里排除这个路由:
protected $except = [ '/api/auth/login', ];
3. 创建认证控制器AuthController
运行命令生成控制器:php artisan make:controller AuthController
然后打开app/Http/Controllers/AuthController.php,编写核心逻辑:
namespace App\Http\Controllers; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Carbon\Carbon; class AuthController extends Controller { public function login(Request $request) { // 验证请求参数 $request->validate([ 'email_address' => 'required|email', // 密码和token二选一 'password' => 'required_without:token', 'token' => 'required_without:password', ]); $timestamp = Carbon::now()->timestamp; $sessionExpires = $timestamp + 3600; // 会话1小时后过期,可按需调整 // 情况1:密码认证 if ($request->has('password')) { // 验证邮箱和密码 if (Auth::attempt([ 'email_address' => $request->email_address, 'password' => $request->password ])) { $user = Auth::user(); // 更新最后登录时间 $user->update(['last_login' => Carbon::now()]); return response()->json([ 'data' => [ [ 'id' => $user->id, 'email_address' => $user->email_address, 'authenticated' => true, 'type' => 'password', 'timestamp' => $timestamp, 'last_login' => $user->last_login->timestamp, 'session_expires' => $sessionExpires ] ] ], 200); } } // 情况2:SSO Token认证 if ($request->has('token')) { // 这里需要根据你的SSO逻辑验证token,比如从缓存/数据库查询关联的用户 // 示例:假设token存储在users表的sso_token字段(你可以根据实际调整) $user = User::where('sso_token', $request->token)->first(); if ($user) { // 更新最后登录时间 $user->update(['last_login' => Carbon::now()]); return response()->json([ 'data' => [ [ 'id' => $user->id, 'email_address' => $user->email_address, 'authenticated' => true, 'type' => 'sso', 'timestamp' => $timestamp, 'last_login' => $user->last_login->timestamp, 'session_expires' => $sessionExpires ] ] ], 200); } } // 认证失败返回401 return response()->json([ 'error' => 'Invalid credentials or token' ], 401); } }
4. 测试API
你可以用Postman、curl或者其他API工具测试:
密码认证请求
- 请求方法:POST
- URL:
http://your-domain/api/auth/login - 请求体(JSON):
{ "email_address": "test@gmail.com", "password": "your-password" }
成功响应会和你给出的示例完全一致。
SSO认证请求
- 请求方法:POST
- URL:
http://your-domain/api/auth/login - 请求体(JSON):
{ "email_address": "test@gmail.com", "token": "your-sso-token" }
成功响应格式和密码认证类似,仅type字段为sso。
注意事项
- SSO Token验证逻辑:上面的示例只是基础实现,你需要根据实际的SSO系统调整(比如调用SSO服务的验证接口,或者从缓存中读取token关联的用户)。
- 密码哈希:创建用户时记得用
Hash::make($password)加密密码,不然Auth::attempt会验证失败。 - 会话过期:
session_expires的时间可以根据你的业务需求调整,比如设置为24小时(86400秒)。 - 错误处理:可以根据不同的失败原因返回更具体的错误信息(比如"Password incorrect"或"Invalid SSO token")。
内容的提问来源于stack exchange,提问作者CodingFlow
相关产品推荐
相关产品推荐

