Laravel+Lighthouse GraphQL如何区分移动端与其他API请求?
区分Laravel Lighthouse GraphQL请求的客户端类型(Web/移动端)
可行方案及实现
1. 优化移动端User-Agent(基础区分)
移动端使用OkHttp时,自定义User-Agent字符串,加入App专属标识,比如:
// Android OkHttp示例 OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(chain -> { Request originalRequest = chain.request(); Request requestWithCustomUA = originalRequest.newBuilder() .header("User-Agent", "MyApp/1.2.3 (Android; 13) Okhttp/7.8.1") .build(); return chain.proceed(requestWithCustomUA); }) .build();
后端Laravel中直接解析UA判断:
$isMobile = str_contains(request()->userAgent(), 'MyApp/');
- 优点:符合HTTP标准,无需额外认证逻辑,快速实现
- 缺点:存在伪造可能,适合非敏感业务场景
2. 结合认证令牌嵌入客户端类型(安全区分)
如果你的应用已经使用JWT或Passport认证,在生成令牌时嵌入客户端类型字段:
// 生成JWT时添加client_type(示例用tymon/jwt-auth) $token = auth()->claims(['client_type' => 'mobile'])->attempt($credentials);
后端通过中间件解析令牌获取客户端类型:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class IdentifyClient { public function handle(Request $request, Closure $next) { $clientType = 'web'; if ($request->bearerToken() && auth()->check()) { $payload = auth()->payload(); if ($payload->get('client_type') === 'mobile') { $clientType = 'mobile'; } } $request->attributes->set('client_type', $clientType); return $next($request); } }
将该中间件注册到Lighthouse的全局中间件列表(config/lighthouse.php的middleware数组),后续在Resolver或业务逻辑中直接调用:
$clientType = request()->attributes->get('client_type');
- 优点:安全性高,令牌签名无法篡改,适合敏感业务
- 缺点:依赖认证系统,需要移动端配合实现令牌逻辑
3. 组合方案(推荐)
将自定义UA和令牌嵌入字段结合使用:
- 公开接口:通过自定义UA快速区分客户端类型
- 需认证接口:优先读取令牌中的
client_type,作为权威判断依据
这种方式兼顾了便捷性和安全性,即使UA被伪造,令牌中的字段也能保证判断的准确性。
注意事项
- 自定义UA时,尽量包含App版本、系统信息,便于后续统计和兼容性处理
- 令牌中的
client_type必须在生成时由可信渠道(比如App登录接口)写入,避免客户端自行修改 - 不要单独依赖自定义请求头区分,伪造成本极低,无安全保障
内容的提问来源于stack exchange,提问作者amit
相关产品推荐
相关产品推荐

