如何验证用户并生成JWT令牌?用户名存用户表,密码存另一表
Great question! Since your user credentials are split across two tables (users for the phone/username and a separate table for passwords/confirmation codes), the default JWTAuth::attempt() method won't work out of the box—it expects credentials to map directly to fields on the main user model. Here's how to handle this properly:
1. Define the Table Relationship First
Assuming your password/confirmation code table is named something like user_credentials (with a user_id foreign key linking to the users table), make sure your User model has a relationship to this table:
// app/Models/User.php public function credentials() { return $this->hasOne(UserCredential::class); }
2. Customize the Authentication Logic
Instead of relying on JWTAuth::attempt(), we'll manually validate the user and their credentials, then generate the token ourselves:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; // Use this if your codes are hashed use JWTAuth; use Tymon\JWTAuth\Exceptions\JWTException; use App\Models\User; public function authenticate(Request $request) { // First, validate incoming request data $request->validate([ 'phone' => 'required|string', 'confirmation_code' => 'required|string', ]); $input = [ 'phone' => $request->phone, 'confirmation_code' => $request->confirmation_code, ]; try { // Step 1: Find the user by phone from the users table $user = User::where('phone', $input['phone'])->first(); if (!$user) { return response()->json(['state' => false, 'error' => 'User not found.'], 404); } // Step 2: Validate the confirmation code against the separate credentials table // If your code is stored as plain text (not recommended!): if (!$user->credentials || $user->credentials->confirmation_code !== $input['confirmation_code']) { // If using hashed codes (always prefer this), replace with: // if (!$user->credentials || !Hash::check($input['confirmation_code'], $user->credentials->confirmation_code)) { return response()->json(['state' => false, 'error' => 'Invalid Credentials.'], 401); } // Step 3: Generate JWT token manually for the validated user $token = JWTAuth::fromUser($user); return response()->json([ 'state' => true, 'token' => $token, 'user' => $user // Optional: return basic user data if needed ]); } catch (JWTException $e) { // Handle token generation failures return response()->json(['state' => false, 'error' => 'Could not create token.'], 500); } }
Key Tips:
- Always Hash Sensitive Data: Never store plain-text confirmation codes or passwords. Use
Hash::make()when saving the code to the database, andHash::check()to validate it (as shown in the commented code). - Enforce Foreign Keys: Ensure the
user_credentialstable has a valid foreign key constraint tousers.idto prevent orphaned credential records. - Request Validation: Adding upfront validation ensures you receive required fields before processing, making error handling more straightforward.
内容的提问来源于stack exchange,提问作者Sina

