From 9a0757922df4d946e8478db95a69beab2eb55bb5 Mon Sep 17 00:00:00 2001 From: Reimar Date: Mon, 2 Sep 2024 13:14:13 +0200 Subject: [PATCH] Fix refresh token API call not working --- API/Application/Users/Commands/LoginUser.cs | 5 ++++- API/Controllers/UsersController.cs | 9 +++------ API/Models/User.cs | 2 +- .../Repositories/IUserRepository.cs | 3 ++- API/Persistence/Repositories/UserRepository.cs | 5 +++++ Mobile/lib/api.dart | 18 ++++++++++++++---- Mobile/lib/base/sidemenu.dart | 5 +---- Mobile/lib/login.dart | 6 +++--- Mobile/lib/main.dart | 6 +++--- 9 files changed, 36 insertions(+), 23 deletions(-) diff --git a/API/Application/Users/Commands/LoginUser.cs b/API/Application/Users/Commands/LoginUser.cs index de90f3d..7576a50 100644 --- a/API/Application/Users/Commands/LoginUser.cs +++ b/API/Application/Users/Commands/LoginUser.cs @@ -34,7 +34,10 @@ namespace API.Application.Users.Commands } var jwtToken = _tokenHelper.GenerateJwtToken(user); - return new OkObjectResult(new { token = jwtToken, id = user.Id, refreshToken = user.RefreshToken}); + user.RefreshToken = System.Guid.NewGuid().ToString(); + _repository.Save(); + + return new OkObjectResult(new { token = jwtToken, id = user.Id, refreshToken = user.RefreshToken }); } } diff --git a/API/Controllers/UsersController.cs b/API/Controllers/UsersController.cs index 07c3c2d..8c83fa0 100644 --- a/API/Controllers/UsersController.cs +++ b/API/Controllers/UsersController.cs @@ -58,15 +58,13 @@ namespace API.Controllers [HttpGet] public async Task>> GetUsers() { - return await _queryAllUsers.Handle(); + return await _queryAllUsers.Handle(); } - [HttpGet("{id}")] public async Task> GetUser(string id) { return await _queryUserById.Handle(id); - } [Authorize] @@ -87,14 +85,13 @@ namespace API.Controllers public async Task DeleteUser(string id) { return await _deleteUser.Handle(id); - } - + } + [HttpPost("/RefreshToken")] public async Task RefreshToken(RefreshTokenDTO refreshTokenDTO) { User user = await _repository.QueryUserByRefreshTokenAsync(refreshTokenDTO.RefreshToken); return new OkObjectResult(_tokenHelper.GenerateJwtToken(user)); } - } } diff --git a/API/Models/User.cs b/API/Models/User.cs index 8bdab07..bfb9b09 100644 --- a/API/Models/User.cs +++ b/API/Models/User.cs @@ -39,7 +39,7 @@ public class UpdateUserDTO public string Password { get; set; } } -public class RefreshTokenDTO +public class RefreshTokenDTO { public string RefreshToken { get; set; } } diff --git a/API/Persistence/Repositories/IUserRepository.cs b/API/Persistence/Repositories/IUserRepository.cs index 3678a6c..9f2584d 100644 --- a/API/Persistence/Repositories/IUserRepository.cs +++ b/API/Persistence/Repositories/IUserRepository.cs @@ -11,5 +11,6 @@ namespace API.Persistence.Repositories Task QueryUserByEmailAsync(string email); Task UpdateUserAsync(User user); Task QueryUserByRefreshTokenAsync(string refreshToken); + void Save(); } -} \ No newline at end of file +} diff --git a/API/Persistence/Repositories/UserRepository.cs b/API/Persistence/Repositories/UserRepository.cs index 3509bd9..e007973 100644 --- a/API/Persistence/Repositories/UserRepository.cs +++ b/API/Persistence/Repositories/UserRepository.cs @@ -78,5 +78,10 @@ namespace API.Persistence.Repositories { return await _context.Users.SingleOrDefaultAsync(u => u.RefreshToken == refreshToken); } + + public void Save() + { + _context.SaveChanges(); + } } } diff --git a/Mobile/lib/api.dart b/Mobile/lib/api.dart index 5bf781f..ed7734f 100644 --- a/Mobile/lib/api.dart +++ b/Mobile/lib/api.dart @@ -51,7 +51,7 @@ Future request(BuildContext? context, ApiService service, String method if (response.statusCode < 200 || response.statusCode >= 300) { try { final json = jsonDecode(response.body); - messenger?.showSnackBar(SnackBar(content: Text(json['message']))); + messenger?.showSnackBar(SnackBar(content: Text(json['message'] ?? json['title']))); debugPrint('API error: ' + json['message']); } catch (e) { debugPrint(e.toString()); @@ -69,7 +69,7 @@ Future isLoggedIn(BuildContext context) async { final token = prefs.getString('token'); if (token == null) { - prefs.remove('id'); + logout(); return false; } @@ -81,15 +81,25 @@ Future isLoggedIn(BuildContext context) async { if (payload['exp'] < DateTime.now().millisecondsSinceEpoch / 1000) { messenger.showSnackBar(const SnackBar(content: Text('Token expired, please sign in again'))); - prefs.remove('token'); + + logout(); return false; } } catch (e) { messenger.showSnackBar(const SnackBar(content: Text('Invalid token, please sign in again'))); - prefs.remove('token'); debugPrint(e.toString()); + + logout(); return false; } return true; } + +void logout() async { + final prefs = await SharedPreferences.getInstance(); + + prefs.remove('token'); + prefs.remove('refresh-token'); + prefs.remove('id'); +} diff --git a/Mobile/lib/base/sidemenu.dart b/Mobile/lib/base/sidemenu.dart index 411db7c..0208d7d 100644 --- a/Mobile/lib/base/sidemenu.dart +++ b/Mobile/lib/base/sidemenu.dart @@ -25,10 +25,7 @@ class _SideMenuState extends State { } void _logout() async { - final prefs = await SharedPreferences.getInstance(); - - prefs.remove('token'); - prefs.remove('id'); + api.logout(); setState(() { user = null; diff --git a/Mobile/lib/login.dart b/Mobile/lib/login.dart index b08790b..87e71f2 100644 --- a/Mobile/lib/login.dart +++ b/Mobile/lib/login.dart @@ -19,15 +19,15 @@ class _LoginPageState extends State { final passwordInput = TextEditingController(); Future _login() async { - final token = await api.request(context, api.ApiService.auth, 'POST', '/api/Users/login', { + final response = await api.request(context, api.ApiService.auth, 'POST', '/api/Users/login', { 'email': emailInput.text, 'password': passwordInput.text, }); - if (token == null) return; + if (response == null) return; // Assuming token is a JSON string - Map json = jsonDecode(token); + Map json = jsonDecode(response); Login jsonUser = Login.fromJson(json); final prefs = await SharedPreferences.getInstance(); diff --git a/Mobile/lib/main.dart b/Mobile/lib/main.dart index 32ba677..d4b720a 100644 --- a/Mobile/lib/main.dart +++ b/Mobile/lib/main.dart @@ -14,11 +14,11 @@ import 'models.dart'; import 'package:http/http.dart' as http; void main() async { + // Refresh JWT on startup final prefs = await SharedPreferences.getInstance(); - debugPrint('token: ' + (prefs.getString('token') ?? '') + ' reffresshh: ' + (prefs.getString("refresh-token") ?? '')); if (prefs.getString("token") != null && prefs.getString("refresh-token") != null) { - final token = await api.request(null, api.ApiService.auth, "POST", "/RefreshToken", {'refresh-token': prefs.getString("refresh-token")}); - debugPrint(token); + final token = await api.request(null, api.ApiService.auth, "POST", "/RefreshToken", {'refreshToken': prefs.getString("refresh-token")}); + if (token != null) prefs.setString("token", token); } runApp(const MyApp());