How to make login in Flutter with PHP MySQL
In this tutorial, we are creating a Flutter Login app with PHP and MySQL.
- First, we are making the PHP http POST request from a Flutter application.
- In the server side, the PHP API reads the POST data from the HTTP request.
- Match username and password with the database and sends the response in JSON format.
Output :
1.Database and Table Creation
Now, the first step is to create the database and the users
table inside the database.
Execute the following SQL queries to create the db_sample
database and users
table inside your MySQL database.
CREATE DATABASE db_sample;
USE db_sample;
CREATE TABLE users ( UID int(10) unsigned NOT NULL AUTO_INCREMENT, NAME varchar(45) NOT NULL DEFAULT '', UNAME varchar(45) NOT NULL DEFAULT '', UPASS varchar(45) NOT NULL DEFAULT '', PRIMARY KEY (UID) );
2.Creating PHP API to Receive the Sent UserName and Password From Flutter App
- First, We have to create a
login_api
folder in yourwww
directory. - Next, create a
user_login.php
file inlogin_api
folder. - Put all the below code inside the
user_login.php
file.
user_login.php
<?php //MySQL database Connection $con=mysqli_connect('localhost','root','','db_sample'); //Received JSON into $json variable $json = file_get_contents('php://input'); //Decoding the received JSON and store into $obj variable. $obj = json_decode($json,true); if(isset($obj["username"]) && isset($obj["password"])){ $uname = mysqli_real_escape_string($con,$obj['username']); $pwd = mysqli_real_escape_string($con,$obj['password']); //Declare array variable $result=[]; //Select Query $sql="SELECT * FROM users WHERE UNAME='{$uname}' and UPASS='{$pwd}'"; $res=$con->query($sql); if($res->num_rows>0){ $row=$res->fetch_assoc(); $result['loginStatus']=true; $result['message']="Login Successfully"; $result["userInfo"]=$row; }else{ $result['loginStatus']=false; $result['message']="Invalid Login Details"; } // Converting the array into JSON format. $json_data=json_encode($result); // Echo the $json. echo $json_data; } ?>
3. Configuring and Coding for App
Adding http.dart package in your dependency
http.dart package is used to transfer data between client and server in JSON form. Open the pubspec.yaml file and find dependencies. Add http: ^0.12.0 as shown as image.
Adding Internet Permission and Allowing HTTP connections
Open android/app/src/main/AndroidManifest.xml
file. Add Internet Permission and Allow HTTP connections as shown as image.
<uses-permission android:name="android.permission.INTERNET"/>
<application android:usesCleartextTraffic="true" />
Creating Login page in Flutter App
main.dart
import 'package:flutter/material.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'home.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Demo Login', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, primaryColor: Color.fromRGBO(235, 31, 42, 1), accentColor: Colors.orange[600], visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Demo Login'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { //For LinearProgressIndicator. bool _visible = false; //Textediting Controller for Username and Password Input final userController = TextEditingController(); final pwdController = TextEditingController(); Future userLogin() async { //Login API URL //use your local IP address instead of localhost or use Web API String url = "http://192.168.43.215/login_api/user_login.php"; // Showing LinearProgressIndicator. setState(() { _visible = true; }); // Getting username and password from Controller var data = { 'username': userController.text, 'password': pwdController.text, }; //Starting Web API Call. var response = await http.post(url, body: json.encode(data)); if (response.statusCode == 200) { //Server response into variable print(response.body); var msg = jsonDecode(response.body); //Check Login Status if (msg['loginStatus'] == true) { setState(() { //hide progress indicator _visible = false; }); // Navigate to Home Screen Navigator.push( context, MaterialPageRoute(builder: (context) => HomePage(uname:msg['userInfo']['NAME']))); } else { setState(() { //hide progress indicator _visible = false; //Show Error Message Dialog showMessage(msg["message"]); }); } } else { setState(() { //hide progress indicator _visible = false; //Show Error Message Dialog showMessage("Error during connecting to Server."); }); } } Future<dynamic> showMessage(String _msg) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: new Text(_msg), actions: <Widget>[ TextButton( child: new Text("OK"), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, ); } final _formKey = GlobalKey<FormState>(); @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( body: SingleChildScrollView( scrollDirection: Axis.vertical, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Visibility( visible: _visible, child: Container( margin: EdgeInsets.only(bottom: 10.0), child: LinearProgressIndicator(), ), ), Container( height: 100.0, ), Icon( Icons.group, color: Theme.of(context).primaryColor, size: 80.0, ), SizedBox( height: 10.0, ), Text( 'Login Here', style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 25.0, fontWeight: FontWeight.bold), ), SizedBox( height: 40.0, ), Form( key: _formKey, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ Theme( data: new ThemeData( primaryColor: Color.fromRGBO(84, 87, 90, 0.5), primaryColorDark: Color.fromRGBO(84, 87, 90, 0.5), hintColor: Color.fromRGBO(84, 87, 90, 0.5), //placeholder color ), child: TextFormField( controller: userController, decoration: InputDecoration( focusedBorder: new OutlineInputBorder( borderSide: BorderSide( color: Color.fromRGBO(84, 87, 90, 0.5), style: BorderStyle.solid, ), ), enabledBorder: new OutlineInputBorder( borderSide: BorderSide( color: Color.fromRGBO(84, 87, 90, 0.5), style: BorderStyle.solid, ), ), errorBorder: new OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.0, style: BorderStyle.solid, ), ), labelText: 'Enter User Name', prefixIcon: const Icon( Icons.person, color: Color.fromRGBO(84, 87, 90, 0.5), ), border: new OutlineInputBorder( borderSide: BorderSide( color: Color.fromRGBO(84, 87, 90, 0.5), style: BorderStyle.solid, ), ), hintText: 'User Name', ), validator: (value) { if (value == null || value.isEmpty) { return 'Please Enter User Name'; } return null; }, ), ), SizedBox( height: 20.0, ), Theme( data: new ThemeData( primaryColor: Color.fromRGBO(84, 87, 90, 0.5), primaryColorDark: Color.fromRGBO(84, 87, 90, 0.5), hintColor: Color.fromRGBO(84, 87, 90, 0.5), //placeholder color ), child: TextFormField( controller: pwdController, obscureText: true, decoration: InputDecoration( focusedBorder: new OutlineInputBorder( borderSide: BorderSide( color: Color.fromRGBO(84, 87, 90, 0.5), style: BorderStyle.solid, ), ), enabledBorder: new OutlineInputBorder( borderSide: BorderSide( color: Color.fromRGBO(84, 87, 90, 0.5), style: BorderStyle.solid, ), ), errorBorder: new OutlineInputBorder( borderSide: BorderSide( color: Colors.red, width: 1.0, style: BorderStyle.solid, ), ), border: new OutlineInputBorder( borderSide: BorderSide( color: Color.fromRGBO(84, 87, 90, 0.5), style: BorderStyle.solid, ), ), labelText: 'Enter Password', prefixIcon: const Icon( Icons.lock, color: Color.fromRGBO(84, 87, 90, 0.5), ), hintText: 'Password', ), validator: (value) { if (value == null || value.isEmpty) { return 'Please Enter Password'; } return null; }, ), ), SizedBox( height: 20.0, ), Padding( padding: const EdgeInsets.all(8.0), child: ElevatedButton( onPressed: () => { // Validate returns true if the form is valid, or false otherwise. if (_formKey.currentState.validate()) {userLogin()} }, child: Padding( padding: EdgeInsets.all(16.0), child: Text( 'Submit', style: TextStyle(fontSize: 18.0), ), ), style: ButtonStyle( backgroundColor: MaterialStateProperty.all<Color>( Theme.of(context).primaryColor), ), ), ), ], ), ), ), ], ), ), )); } }
home.dart
import 'package:flutter/material.dart'; class HomePage extends StatelessWidget { final String uname; HomePage({Key key, @required this.uname}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: const EdgeInsets.all(8.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Center( child: Text( "Welcome : " + uname, style: TextStyle( color: Colors.green, fontSize: 25.0, fontWeight: FontWeight.bold, ), ), ) ], ), ), ); } }