You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 5.6+Passport移动端API认证:注册登录及密钥存储问题

基于Laravel 5.6实现移动端用户注册、登录与持久化API授权

嘿,针对你提出的Laravel 5.6移动端授权需求,我来一步步帮你落地实现——核心用Laravel Passport来搞定资源所有者凭证授权,同时解决client_secret的安全问题,还要满足"手动退出前保持登录"的要求。

一、先搭好Passport基础环境

Laravel 5.6官方推荐用Passport实现OAuth2授权,正好支持你需要的资源所有者凭证(密码授权)模式。

  1. 安装对应版本的Passport:
composer require laravel/passport:^7.0

(Laravel 5.6适配Passport 7.x,别装错版本哦)

  1. 执行迁移生成Passport需要的数据库表:
php artisan migrate
  1. 生成加密密钥和OAuth客户端:
php artisan passport:install

这一步会输出两个客户端信息,重点记好Password Grant Client的client_id和client_secret,后面配置要用。

  1. 给User模型添加Passport的Trait:
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
    
    // 原有的模型代码...
}
  1. 配置Passport路由和令牌有效期:
    在app/Providers/AuthServiceProvider.php的boot方法里添加:
use Laravel\Passport\Passport;

public function boot()
{
    $this->registerPolicies();

    Passport::routes();
    
    // 把令牌有效期拉满(比如10年),满足"手动退出前保持授权"的需求
    Passport::tokensExpireIn(now()->addYears(10));
    Passport::refreshTokensExpireIn(now()->addYears(10));
}
  1. 修改config/auth.php,把API guard的驱动改成passport:
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

二、实现用户注册API

先搞个注册接口,让移动端能创建用户账号:

  1. 创建app/Http/Controllers/Api/RegisterController.php:
namespace App\Http\Controllers\Api;

use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;

class RegisterController extends Controller
{
    public function register(Request $request)
    {
        // 验证请求参数
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);

        // 创建用户
        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        // 注册成功直接生成令牌,让用户自动登录
        $token = $user->createToken('MobileApp')->accessToken;

        return response()->json([
            'access_token' => $token,
            'token_type' => 'Bearer',
            'user' => $user
        ], 201);
    }
}
  1. 在routes/api.php里注册路由:
Route::post('register', 'Api\RegisterController@register');

三、解决client_secret的安全问题

你担心的移动端存储client_secret风险确实存在,这里给你两种靠谱的解决方案:

方案1:后端封装密码授权请求(推荐)

让移动端只传用户名和密码,后端内部带上client_id和client_secret去请求令牌,完全避免客户端暴露敏感信息:

  1. 创建app/Http/Controllers/Api/LoginController.php:
namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;

class LoginController extends Controller
{
    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        // 后端内部调用Passport的密码授权端点
        $response = Http::asForm()->post(config('app.url').'/oauth/token', [
            'grant_type' => 'password',
            'client_id' => env('PASSPORT_PASSWORD_CLIENT_ID'),
            'client_secret' => env('PASSPORT_PASSWORD_CLIENT_SECRET'),
            'username' => $request->email,
            'password' => $request->password,
            'scope' => '',
        ]);

        if ($response->status() !== 200) {
            return response()->json(['message' => '登录失败,用户名或密码错误'], 401);
        }

        return response()->json($response->json());
    }
}
  1. 在.env文件里配置之前拿到的密码客户端信息:
PASSPORT_PASSWORD_CLIENT_ID=2  # 替换成你实际的client_id
PASSPORT_PASSWORD_CLIENT_SECRET=xxxxxx  # 替换成你实际的client_secret
  1. 注册登录路由到routes/api.php:
Route::post('login', 'Api\LoginController@login');

方案2:用个人访问令牌(更简单)

如果不需要严格的OAuth2客户端验证,直接给用户生成个人访问令牌,全程不用管client_secret:

修改LoginController的login方法:

public function login(Request $request)
{
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
    ]);

    // 验证用户名密码
    if (!auth()->attempt($request->only('email', 'password'))) {
        return response()->json(['message' => '登录失败'], 401);
    }

    // 生成永久有效的令牌
    $user = auth()->user();
    $token = $user->createToken('MobileApp')->accessToken;

    return response()->json([
        'access_token' => $token,
        'token_type' => 'Bearer',
        'user' => $user
    ]);
}

四、实现手动退出功能

要让用户能主动退出,就需要撤销当前的访问令牌:

  1. 创建app/Http/Controllers/Api/LogoutController.php:
namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class LogoutController extends Controller
{
    public function logout(Request $request)
    {
        // 撤销当前请求对应的令牌
        $request->user()->token()->revoke();

        return response()->json(['message' => '已成功退出登录']);
    }
}
  1. 注册需要授权的退出路由到routes/api.php:
Route::middleware('auth:api')->post('logout', 'Api\LogoutController@logout');

五、移动端请求示例

  • 登录请求:
POST /api/login
Content-Type: application/json

{
    "email": "user@example.com",
    "password": "password123"
}
  • 返回示例:
{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ij...",
    "token_type": "Bearer",
    "expires_in": 315360000,
    "user": {
        "id": 1,
        "name": "Test User",
        "email": "user@example.com"
    }
}
  • 后续API请求要在请求头带上令牌:
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6Ij...

内容的提问来源于stack exchange,提问作者Varin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:33:28