How to implement user authentication in a Flutter app using shared_preferences and HTTP?
This Flutter code defines a login page that makes use of the shared_preferences and http packages to manage user authentication. The user enters their email and password, which are then sent to the specified API using an HTTP post request. If the login is successful, the API sends back a response containing an authentication token. This token is stored in the app's SharedPreferences so that the user doesn't have to log in again when the app is reopened.
The page is defined as a stateful widget with a boolean _isLoading flag, which is used to show a loading indicator while waiting for the API response. The page includes two TextFormField widgets for the email and password input fields, and an ElevatedButton for the sign-in action. The onPressed function of the sign-in button checks that the email and password fields are not empty and then calls the signIn function to make the API call.
The signIn function uses the http package to make an HTTP POST request to the specified API endpoint, passing in the user's email and password. If the response from the server is successful, the response body is parsed as a JSON object, and the authentication token is stored in the app's SharedPreferences. The Navigator then pushes a new page onto the stack, removing the login page so that the user can continue using the app. If the response is unsuccessful, the _isLoading flag is set to false, and an error message is printed to the console.
Overall, this code provides a simple example of implementing user authentication in a Flutter app using shared_preferences and HTTP.
Here's an example of a login page in Flutter using Shared Preferences and HTTP package:
You can test this Login page with this Username and Password:
Username: eve.holt@reqres.in
Password: cityslicka
Add dependencies to pubspec.yaml:
dependencies:
flutter:
sdk: flutter
http: ^0.13.4
shared_preferences: ^2.0.8
Create a new Dart file login_page.dart.
Here's what this code does:
- The LoginPage widget is defined as a StatefulWidget.
- A boolean variable _isLoading is created and initialized to false. This variable is used to show a loading spinner when the user clicks the sign-in button.
- Two TextEditingController variables emailController and passwordController are created to handle user input for email and password.
- In the build method, the system status bar color is set to transparent, and a Scaffold widget is returned, which contains a Container widget with a background gradient.
- If _isLoading is true, a CircularProgressIndicator is shown. Otherwise, a column of widgets is displayed, including a title, two text fields for email and password, and a sign-in button.
- When the sign-in button is pressed, it calls the signIn method.
- In the signIn method, an instance of SharedPreferences is created to store the user's authentication token. Then, a Map object is created with email and password data. A http post request is sent to a URL endpoint with the data.
- If the request is successful (statusCode 200), the response is decoded from JSON format and the authentication token is stored in SharedPreferences. Then, the user is directed to the MainPage screen using Navigator.of(context).pushAndRemoveUntil().
- If the request is not successful, the _isLoading variable is set to false, and the response body is printed to the console for debugging purposes.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'main.dart';
class LoginPage extends StatefulWidget {
@override
// ignore: library_private_types_in_public_api
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
bool _isLoading = false;
final TextEditingController emailController = new TextEditingController();
final TextEditingController passwordController = new TextEditingController();
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light
.copyWith(statusBarColor: Colors.transparent));
return Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Colors.orange, Colors.orangeAccent],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: _isLoading
? const Center(child: CircularProgressIndicator())
: Column(
children: [
Container(
margin: const EdgeInsets.only(top: 50.0),
padding: const EdgeInsets.symmetric(
horizontal: 20.0, vertical: 30.0),
child: const Text("Login",
style: TextStyle(
color: Colors.black,
fontSize: 40.0,
fontWeight: FontWeight.bold)),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 15.0, vertical: 20.0),
child: Column(
children: <Widget>[
TextFormField(
controller: emailController,
cursorColor: Colors.white,
style: const TextStyle(color: Colors.black),
decoration: const InputDecoration(
icon: Icon(Icons.email, color: Colors.black),
hintText: "Email",
border: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black)),
hintStyle: TextStyle(color: Colors.black),
),
),
const SizedBox(height: 30.0),
TextFormField(
controller: passwordController,
cursorColor: Colors.white,
obscureText: true,
style: const TextStyle(color: Colors.black),
decoration: const InputDecoration(
icon: Icon(Icons.lock, color: Colors.black),
hintText: "Password",
border: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black)),
hintStyle: TextStyle(color: Colors.black),
),
),
],
),
),
Container(
width: MediaQuery.of(context).size.width,
height: 40.0,
padding: const EdgeInsets.symmetric(horizontal: 15.0),
margin: const EdgeInsets.only(top: 15.0),
child: ElevatedButton(
onPressed: emailController.text == "" ||
passwordController.text == ""
? null
: () {
setState(() {
_isLoading = true;
});
signIn(emailController.text,
passwordController.text);
},
child: const Text("Sign In",
style: TextStyle(color: Colors.black)),
),
),
],
),
),
);
}
signIn(String email, pass) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
Map data = {'email': email, 'password': pass};
var jsonResponse = null;
var response =
await http.post(Uri.parse('https://reqres.in/api/login'), body: data);
if (response.statusCode == 200) {
jsonResponse = json.decode(response.body);
if (jsonResponse != null) {
setState(() {
_isLoading = false;
});
sharedPreferences.setString("token", jsonResponse['token']);
// ignore: use_build_context_synchronously
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext context) => const MainPage()),
(Route<dynamic> route) => false);
}
} else {
setState(() {
_isLoading = false;
});
print(response.body);
}
}
}
Paste this code into the main file
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'login.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Login Page",
debugShowCheckedModeBanner: false,
home: const MainPage(),
theme: ThemeData(primaryColor: Colors.orange),
);
}
}
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
// ignore: library_private_types_in_public_api
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
late SharedPreferences sharedPreferences;
@override
void initState() {
super.initState();
checkLoginStatus();
}
checkLoginStatus() async {
sharedPreferences = await SharedPreferences.getInstance();
if (sharedPreferences.getString("token") == null) {
// ignore: use_build_context_synchronously
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) => LoginPage()),
(Route<dynamic> route) => false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:
const Text("Login Screen", style: TextStyle(color: Colors.white)),
actions: <Widget>[
ElevatedButton(
onPressed: () {
sharedPreferences.clear();
// ignore: deprecated_member_use
sharedPreferences.commit();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext context) => LoginPage()),
(Route<dynamic> route) => false);
},
child: const Text("Log Out", style: TextStyle(color: Colors.white)),
),
],
),
body: const Center(child: Text("Main Page")),
drawer: const Drawer(),
);
}
}
Comments
Post a Comment