授权后,将颁发用户令牌,并保存该令牌。如果它在本地存储中可用并且在关闭应用程序后,则不需要进一步授权。这里一切正常,但是有一个 CreatePage 类,它再次需要一个令牌,我在从本地存储中获取它时遇到问题(尽管如果我直接将它插入代码中,它可以工作),服务器返回错误:“401 Unauthorized ”。flutter_secure_storage 库用于存储令牌。
AuthPage.dart
import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:localstorage/localstorage.dart';
import 'package:http/http.dart' as http;
import 'package:digitalpendal/main.dart';
import 'package:digitalpendal/screens/Authentication/RegistrationPage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class AuthPage extends StatefulWidget {
@override
_AuthPageState createState() => _AuthPageState();
}
class _AuthPageState extends State<AuthPage> {
String _email;
String _password;
final LocalStorage storage = new LocalStorage('some_key');
final _sizeTextBlack = const TextStyle(fontSize: 20.0, color: Colors.black);
final _sizeTextWhite = const TextStyle(fontSize: 20.0, color: Colors.white);
final formKey = new GlobalKey<FormState>();
BuildContext _context;
@override
Widget build(BuildContext context) {
_context = context;
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
body: new Center(
child: new Form(
key: formKey,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: "Логин",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
keyboardType: TextInputType.emailAddress,
maxLines: 1,
style: _sizeTextBlack,
onSaved: (val) => _email = val,
validator: (val) =>
!val.contains("@") ? 'Not a valid email.' : null,
),
width: 340.0,
height: 50,
padding: new EdgeInsets.only(top: 10.0),
),
new Padding(padding: new EdgeInsets.only(top: 25.0)),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: "Пароль",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
obscureText: true,
maxLines: 1,
validator: (val) =>
val.length < 2 ? 'Password too short.' : null,
onSaved: (val) => _password = val,
style: _sizeTextBlack,
),
width: 340.0,
height: 50,
padding: new EdgeInsets.only(top: 10.0),
),
new Padding(
padding: new EdgeInsets.only(top: 25.0),
child: new MaterialButton(
onPressed: submit,
color: Theme.of(context).accentColor,
height: 50.0,
minWidth: 150.0,
child: new Text(
"Войти",
style: _sizeTextWhite,
),
),
),
new Padding(
padding: new EdgeInsets.only(top: 25.0),
child: new MaterialButton(
onPressed: submitForm,
color: Colors.white,
height: 50.0,
minWidth: 150.0,
child: new Text(
"Зарегистрироваться",
style: _sizeTextBlack,
),
),
),
],
)),
),
),
);
}
void submit() {
final form = formKey.currentState;
if (form.validate()) {
form.save();
signIn();
}
}
void login() {
final form = formKey.currentState;
if (form.validate()) {
form.save();
submitForm();
}
}
signIn() async {
final storage = new FlutterSecureStorage();
Map data = {
'email': _email,
'password': _password
};
var jsonResponse = null;
var response = await http.post("http://192.168.0.104:8000/api/v1/auth_token/token/login/", body: data);
if(response.statusCode == 200) {
jsonResponse = json.decode(response.body);
if(jsonResponse != null) {
setState(() {
});
await storage.write(key: "auth_token", value: 'auth_token');
Navigator.of(_context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => MyBottomNavigationBar()), (Route<dynamic> route) => false);
}
}
else {
setState(() {
});
print(response.body);
}
}
void hideKeyboard() {
SystemChannels.textInput.invokeMethod('TextInput.hide');
}
void fucktheAuth(){
hideKeyboard();
Navigator.push(_context,
new MaterialPageRoute(builder: (context) => new MyBottomNavigationBar()));
}
void submitForm() {
hideKeyboard();
Navigator.push(_context,
new MaterialPageRoute(builder: (context) => new RegistrationPage()));
}
}
主要.dart
import 'package:digitalpendal/TaskPage.dart';
import 'package:digitalpendal/screens/Authentication/AuthPage.dart';
import 'package:digitalpendal/screens/Create_page/CreatePage.dart';
import 'package:digitalpendal/screens/Profile_Page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
theme: ThemeData(primaryColor: Colors.blue.shade900),
debugShowCheckedModeBanner: false,
home: MyBottomNavigationBar(),
);
}
}
class MyBottomNavigationBar extends StatefulWidget {
@override
_MyBottomNavigationBarState createState() => _MyBottomNavigationBarState();
}
class _MyBottomNavigationBarState extends State<MyBottomNavigationBar> {
final storage = FlutterSecureStorage();
@override
void initState(){
super.initState();
checkLoginStatus();
}
checkLoginStatus() async {
String value = await storage.read(key: 'auth_token');
if(value == null) {
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => AuthPage()), (Route<dynamic> route) => false);
}
}
int _currentIndex = 0;
final List<Widget> _children = [TaskPage(), CreatePage(), Profile_Page()];
void onTappedBar(int index) {
setState(() {
_currentIndex = index;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: false,
body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTappedBar,
currentIndex: _currentIndex,
backgroundColor: Color.fromRGBO(48, 63, 159, 1),
items: [
BottomNavigationBarItem(
icon: new Icon(
Icons.dashboard,
size: 35,
color: Colors.white,
),
title: new Text(
'',
style: new TextStyle(fontSize: 0, color: Colors.white),
),
activeIcon: Theme(
data: ThemeData(
accentColor: Color.fromRGBO(70, 116, 190, 1),
),
child: FloatingActionButton(
elevation: 0,
onPressed: () {},
child: Icon(
Icons.dashboard,
size: 35,
color: Colors.white,),
),
),
),
BottomNavigationBarItem(
icon: new Icon(
Icons.add_circle,
size: 35,
color: Colors.white,
),
title: new Text(
'',
style: new TextStyle(color: Colors.white, fontSize: 0),
),
activeIcon: Theme(
data: ThemeData(
accentColor: Color.fromRGBO(70, 116, 190, 1),
),
child: FloatingActionButton(
elevation: 0,
onPressed: () {},
child: Icon(
Icons.add_circle,
size: 35,
color: Colors.white,),
),
),
),
BottomNavigationBarItem(
icon: new Icon(Icons.account_circle,
size: 35, color: Colors.white),
title: new Text(
'',
style: new TextStyle(fontSize: 0, color: Colors.white),
),
activeIcon: Theme(
data: ThemeData(
accentColor: Color.fromRGBO(70, 116, 190, 1),
),
child: FloatingActionButton(
elevation: 0,
onPressed: () {},
child: Icon(
Icons.account_circle,
size: 35,
color: Colors.white,),
),
),
),
],
));
}
}
创建页面.dart
import 'dart:convert';
import 'package:digitalpendal/main.dart';
import 'package:digitalpendal/screens/Authentication/AuthPage.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:localstorage/localstorage.dart';
import 'package:shared_preferences/shared_preferences.dart';
class CreatePage extends StatefulWidget {
@override
_CreatePageState createState() => _CreatePageState();
}
class _CreatePageState extends State<CreatePage> {
// final LocalStorage storage = new LocalStorage('some_key');
final formKey = new GlobalKey<FormState>();
String _name;
String _description;
String _countPeople;
String _cost;
String _executePeriod;
String value;
final _sizeTextBlack = const TextStyle(fontSize: 20.0, color: Colors.black);
final _sizeTextWhite = const TextStyle(fontSize: 20.0, color: Colors.white);
final storage = FlutterSecureStorage();
@override
void initState(){
super.initState();
checkLoginStatus();
}
checkLoginStatus() async {
String value = await storage.read(key: 'auth_token');
if(value == null) {
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => AuthPage()), (Route<dynamic> route) => false);
}
}
BuildContext _context;
@override
Widget build(BuildContext context) {
_context = context;
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
resizeToAvoidBottomPadding: false,
body: new Center(
child: SingleChildScrollView(
child: new Form(
key: formKey,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Padding(padding: EdgeInsets.only(top: 20.0)),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: "Название работы",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
maxLines: 1,
validator: (val) =>
val.length < 2 ? 'Ввидите название' : null,
onSaved: (val) => _name = val,
style: _sizeTextBlack,
),
width: 340.0,
height: 50,
margin: new EdgeInsets.only(top: 20.0),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: "Сколько людей нужно",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
maxLines: 1,
validator: (val) =>
val.length < 0 ? 'количество меньше 0' : null,
onSaved: (val) => _countPeople = val,
style: _sizeTextBlack,
),
width: 340.0,
height: 50,
margin: new EdgeInsets.only(top: 20.0),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: "Ввидите сумму",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
maxLines: 1,
validator: (val) =>
val.length < 0 ? 'сумма мала' : null,
onSaved: (val) => _cost = val,
style: _sizeTextBlack,
),
width: 340.0,
height: 50,
margin: new EdgeInsets.only(top: 20.0),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: "Срок исполнения",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
maxLines: 1,
validator: (val) =>
val.length < 0 ? 'Введиnt срок выполнения' : null,
onSaved: (val) => _executePeriod = val,
style: _sizeTextBlack,
),
width: 340.0,
height: 50,
margin: new EdgeInsets.only(top: 20.0),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: "краткое описание",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
maxLines: 1,
validator: (val) =>
val.length < 2 ? 'Введите описание' : null,
onSaved: (val) => _description = val,
style: _sizeTextBlack,
),
width: 340.0,
height: 50,
margin: new EdgeInsets.only(top: 20.0),
),
new Padding(padding: new EdgeInsets.only(top: 50.0)),
new MaterialButton(
onPressed: submit,
color: Theme.of(context).accentColor,
height: 50.0,
minWidth: 150.0,
child: new Text(
"Создать",
style: _sizeTextWhite,
),
),
],
)),
),
),
));
}
void submit() {
final form = formKey.currentState;
if (form.validate()) {
form.save();
performLogin(form);
}
}
void performLogin(form) async {
hideKeyboard();
http.Response response = await http.post(
Uri.encodeFull(
'http://192.168.0.104:8000/api/v1/jobs/job/create/'),
headers: {
'Accept': 'application/json',
//'Authorization': 'Token 82b6a5bcf7ad37f45de2a3e89bfea52f23bfb87a'//admin worked hardcore
'Authorization': value
},
body: {
'name': _name,
'description': _description,
'count_people': _countPeople,
'cost': _cost,
'execute_period': _executePeriod
});
if (response.statusCode == 201) {
//storage.setItem('user', jsonEncode(response.body));
hideKeyboard();
Navigator.push(_context,
new MaterialPageRoute(builder: (context) => new MyBottomNavigationBar()));
}
}
void hideKeyboard() {
SystemChannels.textInput.invokeMethod('TextInput.hide');
}
}
