pbp_django_auth
A Flutter package for helping students to implement authentication from Django web service in Flutter.
Getting Started
Django's Part
To use the package, you need to make asynchronous JavaScript (AJAX) login view in your Django project.
-
Run
python manage.py startapp authentication
to make a new app module for handling the AJAX login. -
Add
"authentication"
toINSTALLED_APPS
insettings.py
. -
Run
pip install django-cors-headers
to install the required library. -
Add
"corsheaders"
toINSTALLED_APPS
insettings.py
. -
Add
"corsheaders.middleware.CorsMiddleware"
toMIDDLEWARE
insettings.py
. -
Create a new variable in
settings.py
calledCORS_ALLOW_ALL_ORIGINS
and set the value toTrue
(CORS_ALLOW_ALL_ORIGINS=True
). -
Create a new variable in
settings.py
calledCORS_ALLOW_CREDENTIALS
and set the value toTrue
, (CORS_ALLOW_CREDENTIALS=True
). -
Create the following variables in
settings.py
.CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True CSRF_COOKIE_SAMESITE = 'None' SESSION_COOKIE_SAMESITE = 'None'
-
Create a login view method in
authentication/views.py
.Example Login View
from django.shortcuts import render from django.contrib.auth import authenticate, login as auth_login from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt @csrf_exempt def login(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: if user.is_active: auth_login(request, user) # Redirect to a success page. return JsonResponse({ "status": True, "message": "Successfully Logged In!" # Insert any extra data if you want to pass data to Flutter }, status=200) else: return JsonResponse({ "status": False, "message": "Failed to Login, Account Disabled." }, status=401) else: return JsonResponse({ "status": False, "message": "Failed to Login, check your email/password." }, status=401)
This view will set cookies to the user and allow authenticated requests with @login_required
decorator.
Flutter's Part
To use the package, modify application root widget to provide the CookieRequest
library to all child widgets by using Provider
.
For example, if the previous app initialization was:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter App'),
routes: {
"/login": (BuildContext context) => const LoginPage(),
},
);
}
}
Change it to:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Provider(
create: (_) {
CookieRequest request = CookieRequest();
return request;
},
child: MaterialApp(
title: 'Flutter App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter App'),
routes: {
"/login": (BuildContext context) => const LoginPage(),
},
),
);
}
}
This creates a new Provider
object that will share the CookieRequest
instance with all components in the application.
Usage
To use the package in your project, follow these steps below.
-
Import the
Provider
library and this package to the component.import 'package:provider/provider.dart'; import 'package:pbp_django_auth/pbp_django_auth.dart'; ...
-
Instantiate the
request
object by callingcontext.watch
in the Widgetbuild(BuildContext context)
function.Example
class _LoginPageState extends State<LoginPage> { final _loginFormKey = GlobalKey<FormState>(); bool isPasswordVisible = false; void togglePasswordView() { setState(() { isPasswordVisible = !isPasswordVisible; }); } String username = ""; String password1 = ""; @override Widget build(BuildContext context) { final request = context.watch<CookieRequest>(); // The rest of your widgets are down below ... } }
-
To log in using the package, use the
request.login(url, data)
method.// 'username' and 'password' should be the values of the user login form. final response = await request.login("<DJANGO URL>/auth/login", { 'username': username, 'password': password1, }); if (request.loggedIn) { // Code here will run if the login succeeded. } else { // Code here will run if the login failed (wrong username/password). }
-
To fetch or insert data using the library, use the
request.get(url)
orrequest.post(url, data)
method./* GET request example: */ final response = await request.get(<URL TO ACCESS>); // The returned response will be a Map object with the keys of the JsonResponse /* POST request example: */ final response = await request.post(<URL TO ACCESS>, { "data1": "THIS IS EXAMPLE DATA", "data2": "THIS IS EXAMPLE DATA 2", }); // The data argument should be the keys of the Django form. // The returned response will be a Map obejct with the keys of JsonResponse.
You can also use request.postJson(url, encodedJsonData) with jsonEncode function from 'dart:convert' library to send the submitted data without manually converting the data into JSON format one by one.