After a successful user login (MySQL) , the user gets forwarded to a Mainpage and am working to implement a user profile screen. but if i call the UserView to get the user's username and email i receive a
Forbidden: /accounts/user
HTTP GET /accounts/user 403 [0.01, 192.168.1.2:42536
However doing the same request in browser works: Working browser call here are the relevant views:
class UserRegister(APIView):
permission_classes = (permissions.AllowAny,)
def post(self, request):
clean_data = custom_validation(request.data)
serializer = UserRegisterSerializer(data=clean_data)
if serializer.is_valid(raise_exception=True):
user = serializer.create(clean_data)
if user:
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(clean_data,status=status.HTTP_400_BAD_REQUEST)
class UserLogin(APIView):
permission_classes = (permissions.AllowAny,)
authentication_classes = (SessionAuthentication,)
##
def post(self, request):
data = request.data
assert validate_email(data)
assert validate_password(data)
serializer = UserLoginSerializer(data=data)
if serializer.is_valid(raise_exception=True):
user = serializer.check_user(data)
login(request, user)
return Response(serializer.data, status=status.HTTP_200_OK)
class UserLogout(APIView):
permission_classes = (permissions.AllowAny,)
authentication_classes = ()
def post(self, request):
logout(request)
return Response(status=status.HTTP_200_OK)
class UserView(APIView):
permission_classes = (permissions.IsAuthenticated,)
authentication_classes = (SessionAuthentication,)
def get(self, request):
serializer = UserSerializer(request.user)
return Response({'user': serializer.data}, status=status.HTTP_200_OK)
after a user logs in via :
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:pfeapp/Mainpage/homeview.dart';
class LoginAPI {
static Future<void> loginUser(String email, String password, BuildContext context) async {
const String apiUrl = 'http://192.168.1.3:8000/accounts/login';
final Map<String, dynamic> data = {
'email': email,
'password': password,
};
final String encodedData = jsonEncode(data);
try {
final http.Response response = await http.post(
Uri.parse(apiUrl),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: encodedData,
);
if (response.statusCode == 200) {
final Map<String, dynamic> responseData = json.decode(response.body);
final String email = responseData['email'];
final String password=responseData['password'];
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => HomeView(email: email)),
);
} else {
print('Failed to sign-in. Error: ${response.statusCode}');
}
} catch (error) {
print('Error while signing in: $error');
}
}
}
the user then gets forwarded to HomeView, then after selecting a button from a convexappbar he gets forwarded to a ProfileView: for now its just a button that calls the API for testing:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class User {
final String email;
final String username;
User({
required this.email,
required this.username,
});
}
class ProfileWidget extends StatefulWidget {
const ProfileWidget({super.key});
@override
_ProfileWidgetState createState() => _ProfileWidgetState();
}
class _ProfileWidgetState extends State<ProfileWidget> {
late Future<User> futureUser;
@override
void initState() {
super.initState();
futureUser = fetchUser();
}
Future<User> fetchUser() async {
const String apiUrl = 'http://192.168.1.3:8000/accounts/user';
try {
final response = await http.get(Uri.parse(apiUrl));
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['user'];
return User(
email: jsonData['email'],
username: jsonData['username'],
);
} else {
throw Exception('Failed to load user data');
}
} catch (e) {
throw Exception('Failed to connect to the server');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Profile'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
setState(() {
futureUser = fetchUser();
});
},
child: const Text('Fetch User'),
),
const SizedBox(height: 20),
FutureBuilder<User>(
future: futureUser,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Email: ${snapshot.data!.email}'),
Text('Username: ${snapshot.data!.username}'),
],
);
}
},
),
],
),
),
);
}
}
I've looked into tokens with JWT and set it up in django but i'm unsure if its the solution. i have it functional now per the documentation at:
import 'package:dio/dio.dart';
class AccountApi {
Future<Response> Authtoken(email, password) async {
const String api = "http://192.168.1.3:8000/api/token/";
Response response = await Dio().post(
api,
data: {"email": email, "password": password},
options: Options(
headers: {"Content-Type": "application/json"},
),
);
return response;
}
}