- Published on
Flutter Authentication using OpenID, ABP and IdentityServer4. Part 5
Table of Contents
Intro
In this post we will implement the OAuth for the Flutter app.
1. Adding a new client to the IdentityServer
first step is to create a new client for the nextjs application. list of client is available in the appsettings.json
file at DbMigrator
project.
1.1 Add the new json entry
"Todos_Flutter_2": {
"ClientId": "Todos_Flutter_2",
"RedirectUri": "http://localhost:3000/"
},
1.2 Update the CreateClientsAsync method
In the Domain
project there is a IdentityServerDataSeedContributor
class which has the CreateClientsAsync
method. This method creates the Identity server clients during the migrations. so we will update this method to include the new json entry.
// Flutter2 Client
var flutter2Client = configurationSection["Todos_Flutter_2:ClientId"];
if (!flutter2Client.IsNullOrWhiteSpace())
{
var redirectUrl = configurationSection["Todos_Flutter_2:RedirectUri"];
await CreateClientAsync(
name: flutter2Client,
scopes: commonScopes,
grantTypes: new[] { "authorization_code" },
requireClientSecret: false,
redirectUri: redirectUrl
);
}
1.3 Run the migration
Now run the migration to add the client to the DB.
2. Exposing localhost using ngrok
.\ngrok.exe http https://localhost:44354
3. Creating a flutter app
Create the flutter app
flutter create mytodoapp
Move into the folder
cd mytodoapp
List the devices
flutter devices
Run the app
flutter run
4. Add dependencies
dependencies:
openid_client: ^0.4.1
url_launcher: ^6.0.4
4.1 Update the Android Manifest
Update the android app to use the usesCleartextTraffic
you can find the android manifest in mytodoapp\android\app\src\main
<application
android:usesCleartextTraffic="true"
android:label="mytodos"
android:icon="@mipmap/ic_launcher">
5. Create flutter page to login and logout
import 'package:flutter/material.dart';
import 'package:openid_client/openid_client.dart';
import 'package:openid_client/openid_client_io.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:async';
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final String _clientId = 'Todos_Flutter_2';
static const String _issuer = 'https://d78170304b87.ngrok.io';
final List<String> _scopes = <String>[
'openid',
'profile',
'email',
'offline_access',
'Todos'
];
String logoutUrl = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home"),
),
body: Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
child: Text("Login"),
onPressed: () async {
var tokenInfo = await authenticate(
Uri.parse(_issuer), _clientId, _scopes);
print(tokenInfo.accessToken);
},
),
ElevatedButton(
child: Text("Logout"),
onPressed: () async {
logout();
},
),
],
),
),
),
);
}
Future<TokenResponse> authenticate(
Uri uri, String clientId, List<String> scopes) async {
// create the client
var issuer = await Issuer.discover(uri);
var client = new Client(issuer, clientId);
// create a function to open a browser with an url
urlLauncher(String url) async {
if (await canLaunch(url)) {
await launch(url, forceWebView: true, enableJavaScript: true);
} else {
throw 'Could not launch $url';
}
}
// create an authenticator
var authenticator = new Authenticator(
client,
scopes: scopes,
urlLancher: urlLauncher,
port: 3000,
);
// starts the authentication
var c = await authenticator.authorize();
// close the webview when finished
closeWebView();
var res = await c.getTokenResponse();
setState(() {
logoutUrl = c.generateLogoutUrl().toString();
});
print(res.accessToken);
return res;
}
Future<void> logout() async {
if (await canLaunch(logoutUrl)) {
await launch(logoutUrl, forceWebView: true);
} else {
throw 'Could not launch $logoutUrl';
}
await Future.delayed(Duration(seconds: 2));
closeWebView();
}
}
https://github.com/antosubash/Todos
Github Repo Link :Related Posts
Changing theme for your ABP app. Part 10
In this post we will explore how to change the theme for your ABP application.
Deploy ABP Framework dotnet core tiered app to docker swarm. Part 9
In this post we will see how to deploy your dotnet core app with docker container.
Centralized logging for .net core ABP microservices app using Seq. Part 8
In this post we will see how to implement a central logging system for your ABP app using Seq.