Как получить token из локального хранилища?
При авторизации выдается токен пользователя, который сохраняется. При его наличии в локальном хранилище и после закрытия приложения, дальнейшей авторизацией не требуется. Тут все отрабатывает хорошо, но есть класс 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()));
}
}
main.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,),
),
),
),
],
));
}
}
CreatePage.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');
}
}
Ответы (1 шт):
У вас банальная опечатка в методе checkLoginStatus() (Вы определяете внутреннюю переменную метода, а не класса которую используете в дальнейшем):
String value;
...
checkLoginStatus() async {
value = await storage.read(key: 'auth_token');
if (value == null) {
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) => AuthPage()),
(Route<dynamic> route) => false);
}
}
UPD:
В AuthPage.dart вы записываете вместо вашего token просто строку auth_token:
await storage.write(key: "auth_token", value: 'auth_token');
А должно быть что-то типа этого:
await storage.write(key: "auth_token", value: jsonResponse...);