Authentication
Introduction
Authentication is fundamental to web applications, ensuring secure access for users. In Vania, simplicity, security, and efficiency are prioritized when implementing authentication features.
Vania's authentication system revolves around two key components: guards and providers. Guards determine how users are authenticated for each request, while providers supply user information and authentication mechanisms. Vania uses JSON Web Tokens (JWT) for authentication, providing a secure approach to user validation.
To configure authentication in your Vania application, edit the auth.php
file in the config
directory. This file lets you define how authentication should work in your application.
Whether you're an experienced developer or new to web development, Vania's authentication system is designed to be straightforward while upholding high security standards.
Authentication Quickstart
-
Configure your provider. The provider refers to the model that will supply user data during authentication:
Map<String, dynamic> authConfig = {
'guards': {
'default': {
'provider': User(),
},
}
}; -
Generate and run the auth migration. This migration creates the necessary tables for storing personal access tokens:
vania make:auth
vania migrateNote: Make sure your
.env
file has the correct database configuration before running the migration.
After these steps, your application is ready to handle basic authentication flows and manage user access.
Authenticating a User & Getting a Token
To authenticate a user in Vania, retrieve their data from the provider (e.g., a User
model) and then call the Auth
class:
// Retrieve user data from the model (provider)
final Map<String, dynamic>? user = await User()
.query()
.where('email', '=', request.input('email'))
.first();
// Check if user exists
if (user == null) {
return Response.json({'message': 'User not found'}, 404);
}
// Check if the password matches
if (user['password'].toString() != request.input('password').toString()) {
return Response.json({'message': 'Wrong password'}, 401);
}
// Authenticate the user and generate a token
Map token = Auth()
.login(user)
.createToken(
expiresIn: Duration(hours: 24),
withRefreshToken: true,
);
// Return the token (for example)
return Response.json(token, 200);
Using a Specific Guard
If your app uses multiple guards (like admin
), specify it before calling login
:
Map token = Auth()
.guard('admin')
.login(user)
.createToken(expiresIn: Duration(hours: 24), withRefreshToken: true);
Basic Authentication
In some situations, you may need to use Basic Auth instead of or in addition to JWT. You can pass true
as the second argument to login
for a basic authentication flow:
// Basic authentication
Auth().login(user, true);
Basic Auth Middleware
You can create an authentication middleware that supports Basic Auth by extending the Authenticate
class and enabling basic: true
:
class AuthenticateMiddleware extends Authenticate {
AuthenticateMiddleware({
super.guard,
super.basic,
super.loginPath,
});
}
Then, apply it to your routes:
Router.delete('/home', databaseController.destroy)
.middleware([AuthenticateMiddleware(basic: true)]);
With basic: true
, the AuthenticateMiddleware
will expect Basic Authentication credentials.
Revoking Tokens
If you need to revoke a token, you can use:
// Delete only the current token
Auth().deleteCurrentToken();
// Delete all tokens for the current user
Auth().deleteTokens();
These methods are crucial for managing user sessions, allowing you to immediately invalidate tokens if necessary.
Integrating with Third-Party Databases
If you use a third-party database and don’t want to rely on a local provider, set the provider to null
in your config. Then call:
await Auth().check(token, userPayload);
Here, token
is the JWT or relevant credential, and userPayload
is a map of user data from your external database or service.
Protecting Routes
Use route middleware to ensure only authenticated users can access certain endpoints:
Router.get("/home", homeController.index)
.middleware([AuthenticateMiddleware()]);
Here, AuthenticateMiddleware
checks if the user is authenticated before allowing access to the /home
route.
Getting the Authenticated User
After a user is authenticated, you can retrieve their details with:
// Full user data
Auth().user();
// Only the user ID
Auth().id();
Or, if you use a different guard:
Auth().guard('admin').user();