Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Handling Token Expiration

Premium
6 min read

While doing our final application testing, we noticed that the token expiration was not handled properly. When the token expires, the application crashes. We need to handle this situation gracefully by logging the user out and redirecting them to the login page.

So, let's handle all of the 401 responses from the server and log the user out if the token has expired.


Adding AuthProvider to Api Service

First, we have to modify our API Service to accept AuthProvider. This will allow us to log the user out when the token expires:

import 'package:laravel_api_flutter_app/providers/auth_provider.dart';
 
// ...
 
class ApiService {
late String token;
late AuthProvider? authProvider;
 
ApiService(String token) {
ApiService(String token, AuthProvider? auth) {
token = token;
authProvider = auth;
}
 
// ...

Now, we need to pass that AuthProvider...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

A
aem34 ✓ Link copied!

Hello,

Could you eventually make an example of token expiration for refreshing the token and keeping the login alive while we're still in the application ?

M
Modestas ✓ Link copied!

Hello, well take a look into this :)

ps. With sanctum you can set them to never expire.

HB
Huber Bruno-Nicolas ✓ Link copied!

I may have miss something, At that final point i have something that's not fonctional. I add a transaction with app mobile, when i look at transaction in postman i can see that my user has a new transaction but nothings refresh in mobile app. To be able to see this new transaction i have to cold boot the device. I tried to implement the same structure as from categorise by adding :

@override Widget build(BuildContext context) { return Consumer<TransactionProvider>()

Around the ListTransaction. But it didnt do anything . Also as i'm new with flutter I may be doing something wrong. In api.dart they are some inconsistent structure, in addcatecgory we use final for response not in addtransaction why ? Same for fetchtransactions.

M
Modestas ✓ Link copied!

Main changes to take a look at:

  • https://github.com/LaravelDaily/laravel-api-flutter-app-code/blob/main/lib/main.dart#L27
  • https://github.com/LaravelDaily/laravel-api-flutter-app-code/blob/main/lib/widgets/transaction_add.dart#L11

But specifically, the main.dart file since we need the provider to react to changes.


As for the final and non-final response - I will have to take a look. But it shouldn't cause any big issues (just inconsistency or an example of both ways)

HB
Huber Bruno-Nicolas ✓ Link copied!

Thanks for being so reactive! I understand that you have to show different approaches, and it's really interesting. Just to make sure I didn’t miss anything, I took the commit from the lesson on GitHub and copied everything from the lib folder into my project. However, I’m still experiencing this weird behavior: when I add a new transaction, I have to do a full restart of the app to see it.

M
Modestas ✓ Link copied!

Thanks, we are trying to be reactive!

As for your issue - I'm unable to reproduce it in the full demo from our repository. It seems to instantly display the issue.

This means that there's more debugging needed, which is hard without seeing the code.

What I can suggest to do for you - commit the code that you have into git. Then paste our files on top of your repository and see which files changed. This will give you the reason (via changes list) of what caused your problem!

Hope that helps :)

HB
Huber Bruno-Nicolas ✓ Link copied!

Between my last commit and the main branch from your repo the differences are :

  • my baseUrl in api
  • path to import for all files (as my project did'nt have the same name)
  • some end of file line .

I'll check later if I find something else .

M
Modestas ✓ Link copied!

Hmm, interesting... Maybe something else changed in between the minor versions...

SP
Sylvain P ✓ Link copied!

Coming from a web development background, I find Dart quite tedious. In a world where everything moves fast, I just can’t afford to waste time with a tool that feels heavier than React Native. Most of the time, my needs are simple and don’t require perfect UI design. Plus, it’s yet another dependency on Google. Honestly, I really hope a React version comes out someday.

OB
Oscar Boot ✓ Link copied!

If I logout the current user and login with another user, I keep getting old data, i.e. the data from a previous user. When debugging I found the following:

  1. The new token is issued by the Laravel BE and stored in the FLutterSecureStorage
  2. The CategoryProvider and TransactionProviders use an instance of authProvider with the new token, however
  3. Both providers use an instance of apiProvider with an old token.
  4. This old token is used when accessing the BE.
  5. Because old tokens are not deleted in the BE after logout, the data from the user with the old token is accessed instead of the current user data.

I copied your Github code into my project, however this didn't solve this behaviour. Is this a bug?

M
Modestas ✓ Link copied!

This could be a bug indeed. On logout, we might not clear previous token correctly, or we should add the logout to the api too, where it would delete the token