如何用LaravelAPI实现登录并返回Token?
- 内容介绍
- 文章标签
- 相关推荐
本文共计752个文字,预计阅读时间需要4分钟。
使用 ``Sanctum` 实现登录接口,返回 `token` 是最轻量级、最接近 API 场景的解决方案;无需碰 `Passport`,除非你真的需要 OAuth2 流程。
为什么不用 Auth::attempt() 直接返回 token
很多人写完 Auth::attempt() 就卡住——它只返回布尔值,不生成 token。Laravel 的传统登录是为 Web 表单设计的,session + cookie 路线和纯 API 的 Authorization: Bearer 天然冲突。
-
Auth::attempt()成功后不会自动创建 API token,也不会返回任何可传递给前端的凭证 - 手动调用
$user->createToken()前,必须确保用户已通过认证(否则会创建 token 给任意邮箱/密码组合) - 如果跳过校验直接 createToken,等于绕过密码验证,存在严重安全漏洞
Sanctum 登录接口怎么写才不踩坑
核心逻辑就三步:查用户 → 校验密码 → 发 token。但顺序和异常处理决定是否被重放或爆破。
- 先用
User::where('email', $request->email)->first()查用户,别用Auth::attempt()包裹整个流程——它在失败时会触发 Laravel 默认的“登录失败锁定”,对 API 不友好 - 查到用户后,用
Hash::check($request->password, $user->password)显式比对,失败直接return response(['message' => 'Unauthorized'], 401) - 校验通过再调
$user->createToken('api-token'),返回['token' => $token->plainTextToken]—— 注意是plainTextToken,不是$token->token - 别忘了在
config/auth.php的guards.api中确认 driver 是sanctum,否则中间件会静默失败
POST /login 接口的请求体和响应要严格对齐
前端发过来的字段名、状态码、响应结构,错一个就让调用方反复抓包。
- 接收字段固定为
email和password,别写成username或passwd——Sanctum不处理字段映射 - 成功响应必须是
200,且 body 含token字段,例如:{"token": "1|abc..."}
- 失败一律用
401,别用422(那是表单验证错),也别用500(密码错不是服务器错) - 别在响应里塞
user对象——token 本身不含用户信息,后续请求靠auth:sanctum中间件解析并加载用户
真正容易被忽略的是 token 生命周期和存储位置:默认 Sanctum 的 token 永不过期,靠手动 $user->tokens()->delete() 注销;前端必须把 token 存进 localStorage 或内存变量,不能依赖 cookie,否则跨域请求带不出去。
本文共计752个文字,预计阅读时间需要4分钟。
使用 ``Sanctum` 实现登录接口,返回 `token` 是最轻量级、最接近 API 场景的解决方案;无需碰 `Passport`,除非你真的需要 OAuth2 流程。
为什么不用 Auth::attempt() 直接返回 token
很多人写完 Auth::attempt() 就卡住——它只返回布尔值,不生成 token。Laravel 的传统登录是为 Web 表单设计的,session + cookie 路线和纯 API 的 Authorization: Bearer 天然冲突。
-
Auth::attempt()成功后不会自动创建 API token,也不会返回任何可传递给前端的凭证 - 手动调用
$user->createToken()前,必须确保用户已通过认证(否则会创建 token 给任意邮箱/密码组合) - 如果跳过校验直接 createToken,等于绕过密码验证,存在严重安全漏洞
Sanctum 登录接口怎么写才不踩坑
核心逻辑就三步:查用户 → 校验密码 → 发 token。但顺序和异常处理决定是否被重放或爆破。
- 先用
User::where('email', $request->email)->first()查用户,别用Auth::attempt()包裹整个流程——它在失败时会触发 Laravel 默认的“登录失败锁定”,对 API 不友好 - 查到用户后,用
Hash::check($request->password, $user->password)显式比对,失败直接return response(['message' => 'Unauthorized'], 401) - 校验通过再调
$user->createToken('api-token'),返回['token' => $token->plainTextToken]—— 注意是plainTextToken,不是$token->token - 别忘了在
config/auth.php的guards.api中确认 driver 是sanctum,否则中间件会静默失败
POST /login 接口的请求体和响应要严格对齐
前端发过来的字段名、状态码、响应结构,错一个就让调用方反复抓包。
- 接收字段固定为
email和password,别写成username或passwd——Sanctum不处理字段映射 - 成功响应必须是
200,且 body 含token字段,例如:{"token": "1|abc..."}
- 失败一律用
401,别用422(那是表单验证错),也别用500(密码错不是服务器错) - 别在响应里塞
user对象——token 本身不含用户信息,后续请求靠auth:sanctum中间件解析并加载用户
真正容易被忽略的是 token 生命周期和存储位置:默认 Sanctum 的 token 永不过期,靠手动 $user->tokens()->delete() 注销;前端必须把 token 存进 localStorage 或内存变量,不能依赖 cookie,否则跨域请求带不出去。

