Laravel+Sanctum API存储访客(登录/未登录)国家信息的标准方案咨询
Laravel+Sanctum API 访客国家存储与身份识别方案
针对无服务器端会话的API场景下,存储访客国家信息并识别用户的需求,以下是几个落地性强的方案:
一、客户端本地存储 + 请求头携带
这是API场景下最常用的方案,完全避开服务器端会话依赖:
- 首次请求处理:
- 用户首次请求时,服务器通过
request()->ip()获取IP,用GeoIP工具(比如laravel/geoip包)解析出国家代码/名称。 - 生成唯一访客ID(用
Str::uuid()),和国家信息一起返回给React Native客户端。
- 用户首次请求时,服务器通过
- 客户端存储:
- RN用
AsyncStorage或性能更好的MMKV存储访客ID和国家信息。
- RN用
- 后续请求携带:
- 客户端每次请求时,在请求头里添加
X-Visitor-ID和X-User-Country字段,把存储的信息传过来。
- 客户端每次请求时,在请求头里添加
- Laravel校验逻辑:
- 写一个全局中间件,从请求头读取字段并存入请求实例:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class AttachVisitorInfo { public function handle(Request $request, Closure $next) { $visitorId = $request->header('X-Visitor-ID'); $country = $request->header('X-User-Country'); // 可选:用IP再次校验国家,防止客户端篡改 if ($country) { $ipCountry = app('geoip')->getLocation($request->ip())->country; if ($ipCountry !== $country) { $country = $ipCountry; } } $request->merge([ 'visitor_id' => $visitorId, 'user_country' => $country ]); return $next($request); } } - 在
app/Http/Kernel.php中注册该中间件,作用于所有API路由。
- 写一个全局中间件,从请求头读取字段并存入请求实例:
二、扩展Sanctum令牌(匿名令牌/个人访问令牌)
利用Laravel Sanctum的令牌机制,把访客信息嵌入令牌Payload:
- 匿名令牌(Laravel 10+支持):
- 首次请求时,解析IP得到国家,生成匿名令牌并附加自定义Claims:
use Laravel\Sanctum\PersonalAccessToken; use Illuminate\Support\Str; $visitorId = Str::uuid(); $country = app('geoip')->getLocation(request()->ip())->country; $token = PersonalAccessToken::createToken( 'anonymous-visitor', ['visitor_id' => $visitorId, 'country' => $country], now()->addDays(7) // 设置7天有效期 ); return response()->json([ 'token' => $token->plainTextToken, 'visitor_id' => $visitorId, 'country' => $country ]);
- 首次请求时,解析IP得到国家,生成匿名令牌并附加自定义Claims:
- 客户端携带令牌:
- RN把令牌存在本地存储,每次请求在
Authorization头里携带Bearer {token}。
- RN把令牌存在本地存储,每次请求在
- Laravel解析令牌:
- 在中间件或控制器里读取令牌中的自定义字段:
$token = $request->user()?->currentAccessToken() ?? PersonalAccessToken::findToken($request->bearerToken()); $visitorId = $token?->claims()->get('visitor_id'); $country = $token?->claims()->get('country'); // 可选:用IP校验国家信息
- 在中间件或控制器里读取令牌中的自定义字段:
- 登录用户处理:
- 用户登录后,可在用户表新增
country字段存储国家信息,后续使用个人访问令牌时可附加该字段,优先用用户关联的国家信息。
- 用户登录后,可在用户表新增
三、Cookie存储(备选)
如果RN项目能较好处理Cookie(比如用react-native-cookies库),可采用服务器端Cookie存储:
- Laravel设置Cookie:
- 首次请求时生成访客ID和解析国家,设置HttpOnly Cookie:
return response()->json([/* 响应数据 */]) ->cookie('visitor_id', $visitorId, 60*24*7) // 7天有效期 ->cookie('user_country', $country, 60*24*7);
- 首次请求时生成访客ID和解析国家,设置HttpOnly Cookie:
- RN配置Cookie携带:
- 确保请求时携带Cookie,同时Laravel Sanctum的CORS配置需开启
supports_credentials:
在config/cors.php中设置'supports_credentials' => true。
- 确保请求时携带Cookie,同时Laravel Sanctum的CORS配置需开启
- Laravel读取Cookie:
- 中间件里直接从
$request->cookie('visitor_id')和$request->cookie('user_country')获取信息,同样可做IP校验。
- 中间件里直接从
关键注意事项
- 防止篡改:无论用哪种方案,建议用IP解析结果对客户端传来的国家信息做校验,避免恶意伪造。
- 数据持久化:若需长期识别访客,可在服务器端建
visitors表存储访客ID和国家信息,后续通过访客ID关联业务数据。 - 性能优化:IP解析建议用本地GeoIP库(比如
laravel/geoip搭配MaxMind数据库),避免频繁调用第三方API导致延迟。
内容的提问来源于stack exchange,提问作者RP McMurphy
相关产品推荐
相关产品推荐

