flutter - 如何在 Flutter 的页面认证中保存用户登录?
问题描述
我有一个授权页面,一切正常,我在服务器上登录,没有任何问题。但是我有一个问题,我不能这样做,当我登录以在下一次授权时将我的登录信息保存在系统中时(即通过单击登录字段,我必须看到至少最后 3 个已被授权的唯一登录信息,然后我只选择了我需要的登录名并输入我的密码)我的页面验证码:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:io';
import 'package:flutter_app_seals/model/setting/globalvar.dart' as global;
import 'package:flutter_aes_ecb_pkcs5/flutter_aes_ecb_pkcs5.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_app_seals/model/user_page/page.dart' ;
class Login extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new LoginPage(
storage: Storage()
)
);
}
}
class LoginPage extends StatefulWidget {
final Storage storage;
LoginPage({Key key, @required this.storage}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
//Info about users
String state;
@override
void initState() {
super.initState();
widget.storage.readData().then((String value) {
setState(() {
global.urlVar = value;
});
});
}
bool _isLoading = false;
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light.copyWith(statusBarColor: Colors.transparent));
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.white],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: _isLoading ? Center(child: CircularProgressIndicator()) : ListView(
children: <Widget>[
headerSection(),
textSection(),
buttonSection(),
],
),
),
);
}
signIn(String login, pass) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
var AESLogin = login;
var AESpass = pass;
//generate a 16-byte random key
var key = '1212121211121112';
print(key);
//encrypt
var encryptLogin = await FlutterAesEcbPkcs5.encryptString(AESLogin, key);
var encryptPass = await FlutterAesEcbPkcs5.encryptString(AESpass, key);
HttpClient client = new HttpClient();
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
String url = global.urlVar + "/auth";
Map map = {
"login": encryptLogin,
"pass": encryptPass
};
HttpClientRequest request = await client.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(map)));
HttpClientResponse response = await request.close();
var responseBody = await response.transform(utf8.decoder).join();
Map jsonResponse = json.decode(responseBody);
print(jsonResponse);
if (response.statusCode == 200) {
if (jsonResponse['message'] ==
'200') { //if( jsonResponse['message'] == '200') {
setState(() {
_isLoading = false;
});
global.nameUser = jsonResponse['name'];
global.dataArea = jsonResponse['data_area'];
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => UserPage()),
).then((value) {
setState(( ) {});
});
}
else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Error_Auth()),
);
}
}
else {
setState(() {
_isLoading = false;
});
}
}
Container buttonSection() {
return Container(
width: MediaQuery.of(context).size.width,
height: 40.0,
padding: EdgeInsets.symmetric(horizontal: 15.0),
margin: EdgeInsets.only(top: 15.0),
child: RaisedButton(
onPressed: emailController.text == "" || passwordController.text == "" ? null : () {
setState(() {
_isLoading = true;
});
signIn(emailController.text, passwordController.text);
},
elevation: 0.0,
color: Colors.purple,
child: Text("SingIn", style: TextStyle(color: Colors.white70)),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)),
),
);
}
final TextEditingController emailController = new TextEditingController();
final TextEditingController passwordController = new TextEditingController();
Container textSection() {
return Container(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0),
child: Column(
children: <Widget>[
TextFormField(
controller: emailController,
cursorColor: Colors.white,
style: TextStyle(color: Colors.white70),
decoration: InputDecoration(
icon: Icon(Icons.login, color: Colors.white70),
hintText: "Login",
border: UnderlineInputBorder(borderSide: BorderSide(color: Colors.white70)),
hintStyle: TextStyle(color: Colors.white70),
),
),
SizedBox(height: 30.0),
TextFormField(
controller: passwordController,
cursorColor: Colors.white,
obscureText: true,
style: TextStyle(color: Colors.white70),
decoration: InputDecoration(
icon: Icon(Icons.lock, color: Colors.white70),
hintText: "Pass",
border: UnderlineInputBorder(borderSide: BorderSide(color: Colors.white70)),
hintStyle: TextStyle(color: Colors.white70),
),
),
],
),
);
}
Container headerSection() {
return Container(
alignment: Alignment.topCenter,
margin: EdgeInsets.only(top: 50.0),
child: Text("Пломби",
style: TextStyle(
color: Colors.white70,
fontSize: 40.0,
fontWeight: FontWeight.bold)),
);
}
}
class Error_Auth extends StatelessWidget {
@override
Widget build(BuildContext context) {
final AlertDialog dialog = AlertDialog(
title: Text('Помилка при авторизації'),
content:
Text('Повторити спробу авторизації'),
actions: [
FlatButton(
textColor: Color(0xFF6200EE),
onPressed: () => SystemNavigator.pop(),
child: Text('Ні'),
),
FlatButton(
textColor: Color(0xFF6200EE),
onPressed: () { Navigator.push(
context,MaterialPageRoute(builder: (context) => Login()),
);
},
child: Text('Так'),
),
],
);
return Scaffold(
body:dialog
);
}
}
class Storage {
Future<String> get localPath async {
final dir = await getApplicationDocumentsDirectory();
return dir.path;
}
Future<File> get localFile async {
final path = await localPath;
return File('$path/db.txt');
}
Future<String> readData() async {
try {
final file = await localFile;
String body = await file.readAsString();
return body;
} catch (e) {
return e.toString();
}
}
Future<File> writeData(String data) async {
final file = await localFile;
return file.writeAsString("$data");
}
}
解决方案
我认为首先您需要将 textformfields 包装在 Form 字段中,并向表单添加一个键--GlobalKey 这也将帮助您验证数据,如果您需要保存数据以供以后使用,也许您可以使用 onSaved 属性考虑一下。
推荐阅读
- java - 弹性搜索查询不适用于 java 但使用弹性 URI
- amazon-web-services - 输入 S3 listObjectsV2 API 调用的存储桶名称?
- git - git可以更新文件但不跟踪它吗?
- python - 我们如何在python中检测鼠标双击?
- reactjs - React zodResolver 放置约束日期应该大于现在
- tensorflow - 找不到“tf.quantization.fake_quant_with_min_max_args”的源代码
- flutter - setState 不更新 UI
- amazon-web-services - AWS API Gateway 与 Cloudformation 脚本中的 AWS 事件桥(Cloudwatch 事件)集成
- python - 如何获得所有行的最大数量?
- sql-server - 如何从脚本文件创建 DacPac 以自动化数据库部署?