# JWT Authentication Implementation Guide

This document describes the JWT authentication implementation for the Web Dolphin Japan Laravel 12 API.

## Overview

JWT (JSON Web Token) authentication has been implemented using the `tymon/jwt-auth` package, providing stateless token-based authentication for API endpoints.

## What Was Implemented

### 1. **JWT Package Installation**
- Installed `tymon/jwt-auth` v2.3.0 and dependencies
- Generated JWT secret key (stored in `.env` as `JWT_SECRET`)

### 2. **User Model Updates**
- File: [app/Models/User.php](app/Models/User.php)
- Implemented `JWTSubject` interface
- Added `getJWTIdentifier()` method
- Added `getJWTCustomClaims()` method

### 3. **Authentication Configuration**
- File: [config/auth.php](config/auth.php)
- Added `api` guard with JWT driver
- Configured user provider for API authentication

### 4. **AuthController Implementation**
- File: [app/Http/Controllers/AuthController.php](app/Http/Controllers/AuthController.php)
- **register**: Register new user and return user data
- **login**: Authenticate user and return JWT token + user info
- **logout**: Invalidate JWT token
- **getUser**: Retrieve authenticated user details
- **updateUser**: Update user profile (email, name, phone)
- **refreshToken**: Refresh expired JWT token

### 5. **JWT Middleware**
- File: [app/Http/Middleware/JwtMiddleware.php](app/Http/Middleware/JwtMiddleware.php)
- Validates JWT token on protected routes
- Returns 401 error if token is invalid or missing

### 6. **Middleware Registration**
- File: [bootstrap/app.php](bootstrap/app.php)
- Registered `jwt` middleware alias for route protection

### 7. **API Routes**
- File: [routes/web.php](routes/web.php)

#### Public Routes (No Authentication Required)
```
POST   /api/v1/auth/register     - Register a new user
POST   /api/v1/auth/login        - Login and get JWT token
```

#### Protected Routes (JWT Token Required)
```
GET    /api/v1/auth/user         - Get current user details
PUT    /api/v1/auth/user         - Update user profile
POST   /api/v1/auth/logout       - Logout and invalidate token
POST   /api/v1/auth/refresh      - Refresh JWT token
```

## API Usage Examples

### 1. Register a New User
```bash
POST /api/v1/auth/register
Content-Type: application/json

{
  "first_name": "John",
  "last_name": "Doe",
  "username": "johndoe",
  "email": "john@example.com",
  "password": "password123",
  "phone_no": "+1234567890"
}
```

**Response (201 Created)**
```json
{
  "code": 201,
  "hasError": false,
  "result": "User registered successfully"
}
```

### 2. Login
```bash
POST /api/v1/auth/login
Content-Type: application/json

{
  "username": "johndoe",
  "password": "password123"
}
```

**Response (200 OK)**
```json
{
  "code": 200,
  "hasError": false,
  "result": {
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "expires_in": 3600,
    "user": {
      "id": 1,
      "first_name": "John",
      "last_name": "Doe",
      "username": "johndoe",
      "email": "john@example.com",
      "phone_no": "+1234567890",
      "is_active": 1,
      "is_email_verified": 0,
      "created_at": "2026-05-17T10:30:00.000000Z",
      "updated_at": "2026-05-17T10:30:00.000000Z"
    }
  }
}
```

### 3. Get Current User (With Token)
```bash
GET /api/v1/auth/user
Authorization: Bearer <JWT_TOKEN>
```

**Response (200 OK)**
```json
{
  "code": 200,
  "hasError": false,
  "result": {
    "id": 1,
    "first_name": "John",
    "last_name": "Doe",
    "username": "johndoe",
    "email": "john@example.com",
    "phone_no": "+1234567890",
    "is_active": 1,
    "is_email_verified": 0,
    "created_at": "2026-05-17T10:30:00.000000Z",
    "updated_at": "2026-05-17T10:30:00.000000Z"
  }
}
```

### 4. Update User Profile (With Token)
```bash
PUT /api/v1/auth/user
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json

{
  "first_name": "Jane",
  "email": "jane@example.com",
  "phone_no": "+1987654321"
}
```

**Response (200 OK)**
```json
{
  "code": 200,
  "hasError": false,
  "result": {
    "id": 1,
    "first_name": "Jane",
    "last_name": "Doe",
    "username": "johndoe",
    "email": "jane@example.com",
    "phone_no": "+1987654321",
    "is_active": 1,
    "is_email_verified": 0,
    "created_at": "2026-05-17T10:30:00.000000Z",
    "updated_at": "2026-05-17T10:35:00.000000Z"
  }
}
```

### 5. Refresh Token (With Token)
```bash
POST /api/v1/auth/refresh
Authorization: Bearer <JWT_TOKEN>
```

**Response (200 OK)**
```json
{
  "code": 200,
  "hasError": false,
  "result": {
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
    "expires_in": 3600
  }
}
```

### 6. Logout (With Token)
```bash
POST /api/v1/auth/logout
Authorization: Bearer <JWT_TOKEN>
```

**Response (200 OK)**
```json
{
  "code": 200,
  "hasError": false,
  "result": []
}
```

## Error Responses

### Invalid Credentials
```json
{
  "code": 401,
  "hasError": true,
  "message": "Invalid username or password"
}
```

### Missing or Invalid Token
```json
{
  "code": 401,
  "hasError": true,
  "message": "Unauthorized"
}
```

### Validation Error
```json
{
  "code": 422,
  "hasError": true,
  "message": "Validation failed",
  "errors": {
    "username": ["The username field is required"],
    "password": ["The password must be at least 6 characters"]
  }
}
```

## Configuration

### Environment Variables
- `JWT_SECRET`: JWT signing key (generated via `php artisan jwt:secret`)
- `AUTH_GUARD`: Default guard (not used in API, can be 'web')

### JWT Config
The JWT package auto-configures with default settings:
- **Algorithm**: HS256
- **TTL**: 3600 seconds (1 hour)
- **Refresh TTL**: 20160 minutes (14 days)

To customize, publish the JWT config:
```bash
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
```

## Testing

### Using Postman
1. **Register**: POST to `/api/v1/auth/register` with user data
2. **Login**: POST to `/api/v1/auth/login` to get token
3. **Protected Routes**: Add `Authorization: Bearer <TOKEN>` header to requests
4. **Logout**: POST to `/api/v1/auth/logout` with token to invalidate

### Using cURL
```bash
# Login
curl -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"johndoe","password":"password123"}'

# Get user (with token)
curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  http://localhost:8000/api/v1/auth/user
```

## Security Considerations

1. **Token Storage**: Never store tokens in localStorage (XSS vulnerability)
2. **HTTPS**: Always use HTTPS in production
3. **Token Expiration**: Tokens expire after 1 hour by default
4. **Refresh Tokens**: Use `/auth/refresh` to extend session
5. **Password Hashing**: Passwords are hashed with bcrypt (Laravel default)

## Integration with Protected Routes

To protect any route with JWT:

```php
Route::middleware('jwt')->group(function () {
    Route::get('/protected', [YourController::class, 'action']);
});
```

## Troubleshooting

### Issue: "Could not create token"
- Ensure JWT_SECRET is set in `.env`
- Restart your application server

### Issue: "Unauthorized" on protected routes
- Check token is included in Authorization header
- Verify token format: `Authorization: Bearer <TOKEN>`
- Ensure token hasn't expired

### Issue: "Invalid username or password"
- Verify username exists in database
- Confirm password is correct
- Check user's `is_active` field is 1

## Files Modified/Created

- ✅ [app/Models/User.php](app/Models/User.php) - Updated with JWTSubject
- ✅ [app/Http/Controllers/AuthController.php](app/Http/Controllers/AuthController.php) - JWT methods
- ✅ [app/Http/Middleware/JwtMiddleware.php](app/Http/Middleware/JwtMiddleware.php) - NEW
- ✅ [config/auth.php](config/auth.php) - JWT guard added
- ✅ [bootstrap/app.php](bootstrap/app.php) - Middleware alias
- ✅ [routes/web.php](routes/web.php) - Protected routes added
- ✅ [.env](.env) - JWT_SECRET added

## Next Steps

1. ✅ Test all endpoints with Postman/cURL
2. ✅ Update API documentation with JWT requirements
3. Consider implementing:
   - Email verification before allowing login
   - Refresh token rotation for enhanced security
   - Rate limiting on login attempts
   - User roles and permissions
   - Token blacklisting on logout

---

For more information, visit: [tymon/jwt-auth Documentation](https://jwt-auth.readthedocs.io/)
