This project is a starter template for building a Laravel 10 REST API with JWT (JSON Web Token) authentication. It provides endpoints for user login, retrieving user information, refreshing tokens, and logging out. The project is intended to serve as a boilerplate and has been uploaded to GitHub as a public repository.
-
Clone the repository:
git clone https://github.com/ph-hitachi/laravel-api-jwt-starter.git
-
Navigate to the project directory:
cd laravel-api-jwt-starter
-
Install the required dependencies using Composer::
composer install
-
Set up your environment variables by copying the
.env.example
file:cp .env.example .env
-
Generate a new application key:
php artisan key:generate
-
Configure your database connection in the
.env
file. -
Run the migrations:
php artisan migrate
-
Generate a JWT secret key:
php artisan jwt:secret
Method | Endpoint | Description |
---|---|---|
POST | /api/login | User login and token generation |
GET | /api/me | Get current user information |
POST | /api/refresh | Refresh access token |
POST | /api/logout | Invalidate the current token and log out |
Use this endpoint to authenticate a user and generate an access token. Provide the user's email and password in the request body. If the credentials are valid, the API will respond with the user's information along with an access token that can be used for subsequent requests.
POST /api/login HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{
"email": "[email protected]",
"password": "password@123"
}
{
"user": {
"id": 1,
"name": "john doe",
"email": "[email protected]",
"email_verified_at": null,
"created_at": "2023-07-24T05:10:20.000000Z",
"updated_at": "2023-07-24T05:10:20.000000Z"
},
"authorization": {
"access_token": "{{ token }}",
"token_type": "bearer",
"expires_in": 3600
}
}
Use this endpoint to fetch information about the currently authenticated user. Include the access token in the request headers. The API will respond with the user's details.
GET /api/me HTTP/1.1
Host: localhost:8000
Content-Type: application/json
Authorization: Bearer <token>
{
"id": 1,
"name": "john doe",
"email": "[email protected]",
"email_verified_at": null,
"created_at": "2023-07-24T05:10:20.000000Z",
"updated_at": "2023-07-24T05:10:20.000000Z"
}
Use this endpoint to refresh an expired access token. Include the current access token in the request headers. The API will respond with a new access token that can be used for authentication. Token refresh is useful to maintain a user's session without requiring frequent logins.
POST /api/refresh HTTP/1.1
Host: localhost:8000
Content-Type: application/json
Authorization: Bearer <token>
{
"user": {
"id": 1,
"name": "john doe",
"email": "[email protected]",
"email_verified_at": null,
"created_at": "2023-07-24T05:10:20.000000Z",
"updated_at": "2023-07-24T05:10:20.000000Z"
},
"authorization": {
"access_token": "{{ token }}",
"token_type": "bearer",
"expires_in": 3600
}
}
Use this endpoint to invalidate the current access token and log out the user. Include the access token in the request headers. After logging out, the token will no longer be valid for making authenticated requests.
POST /api/logout HTTP/1.1
Host: localhost:8000
Content-Type: application/json
Authorization: Bearer <token>
{
"success": true
}
In case of errors, the API will return responses in JSON format. The following table lists the fields you might encounter in error responses along with their descriptions:
Field | Description |
---|---|
error | The top-level container for error information |
error.message | A human-readable description of the error |
error.type | A categorization of the error type |
error.code | A specific code or identifier for the error |
error.trace_id | A unique identifier for tracing the error |
error.validation | An object containing field-specific errors |
-
error.message: This field provides a human-readable description of the error that occurred. It can help you identify the nature of the problem quickly.
-
error.type: This field categorizes the type of error that occurred. It can be helpful for programmatically handling different types of errors, such as authentication, validation, or server errors.
-
error.code: An error-specific code or identifier that can be used for easier identification and handling of errors in your codebase.
-
error.trace_id: A unique identifier associated with the error. This trace ID can be helpful for diagnosing issues and troubleshooting, as it can be used to locate relevant logs and traces.
-
error.validation: If the error is related to input validation, this object may contain detailed information about which fields failed validation and why. It helps pinpoint the exact issues with the submitted data.
It's important to parse and handle these error responses appropriately in your application to provide meaningful feedback to users and to aid in debugging and improving the system.
Here's an example of an error response:
{
"error": {
"message": "The provided token is invalid, has expired, or has been blacklisted.",
"type": "OAuthException",
"code": "token_could_not_verified",
"trace_id": "qOoyG0cl3R8B4x9j"
}
}
Remember that the specific field names and structures of error responses might vary based on the API implementation.
Feel free to adjust the descriptions and add any other relevant information to suit your project's requirements.
JSON Web Tokens (JWTs) are a secure way to authenticate users in stateless environments. Here's how the security is maintained:
-
Token Expiration: JWT tokens have an expiration time (expiry). After a token expires, it's no longer valid for authentication. This ensures that if a token is intercepted, it can only be used for a limited time.
-
Token Refresh: When an access token expires, the user can use the refresh token to obtain a new access token without having to re-enter their credentials. The refresh token is typically long-lived and is used to generate new access tokens.
-
Token Blacklisting: While expired tokens can't be used for authentication, they can be blacklisted to ensure that even if an attacker gets hold of a valid token, it won't work after being blacklisted. Laravel has a built-in blacklist mechanism for this purpose.
-
Statelessness: JWTs are self-contained and do not require server-side storage. This makes JWT-based authentication suitable for scalable and distributed systems.
When an access token expires, the user can use the refresh token to request a new access token. This is done by making a request to the /api/refresh
endpoint, providing the expired token in the authorization header. The API then responds with a new access token, extending the user's session.
If a token is compromised or a user logs out, their tokens can be blacklisted. Blacklisting means that even if an expired token is used for refresh, the new access token won't be generated. Laravel's built-in mechanism takes care of blacklisting tokens to enhance security.
It's important to implement proper token handling and security practices to protect user data and maintain system integrity.
The Laravel framework is open-sourced software licensed under the MIT license.