mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-08-06 17:48:43 +08:00
添加 github oAuth 认证,添加错误提醒
This commit is contained in:
@ -14,6 +14,7 @@
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="fluttergo"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:icon="@mipmap/ic_launcher_logo">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
BIN
assets/images/gitHub.png
Normal file
BIN
assets/images/gitHub.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
@ -1,10 +1,14 @@
|
||||
class Api{
|
||||
// static const String BASE_URL = 'http://127.0.0.1:6001/';
|
||||
static const String BASE_URL = 'http://flutter-go.alibaba.net/';
|
||||
static const String BASE_URL = 'http://30.10.29.190:6001/';
|
||||
// static const String BASE_URL = 'http://flutter-go.alibaba.net/';
|
||||
|
||||
static const String DO_LOGIN = BASE_URL+'doLogin';//登陆
|
||||
|
||||
static const String CHECK_LOGIN = BASE_URL+'checkLogin';//验证登陆
|
||||
|
||||
static const String LOGOUT = BASE_URL+'logout';//退出登陆
|
||||
|
||||
static const String GET_USER_INFO = BASE_URL+'getUserInfo';//获取用户信息
|
||||
|
||||
static const String RedirectIp = 'http://100.81.211.172/';
|
||||
}
|
@ -93,6 +93,7 @@ class _WidgetDemoState extends State<WidgetDemo> {
|
||||
ApplicationEvent.event
|
||||
.fire(CollectionEvent(widget.title, _router, true));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
print('删除错误');
|
||||
|
@ -5,3 +5,9 @@ class CollectionEvent{
|
||||
// token uid...
|
||||
CollectionEvent(this.widgetName,this.router,this.isRemove);
|
||||
}
|
||||
|
||||
class UserGithubOAuthEvent{
|
||||
final String loginName;
|
||||
final bool isSuccess;
|
||||
UserGithubOAuthEvent(this.loginName,this.isSuccess);
|
||||
}
|
@ -4,25 +4,37 @@ import './net_utils.dart';
|
||||
import '../model/user_info.dart';
|
||||
import 'package:flutter_go/api/api.dart';
|
||||
|
||||
|
||||
class DataUtils{
|
||||
class DataUtils {
|
||||
// 登陆获取用户信息
|
||||
static Future<UserInfo> doLogin(Map<String,String> params) async{
|
||||
static Future doLogin(Map<String, String> params) async {
|
||||
var response = await NetUtils.post(Api.DO_LOGIN, params);
|
||||
print(response);
|
||||
try {
|
||||
UserInfo userInfo = UserInfo.fromJson(response['data']);
|
||||
return userInfo;
|
||||
} catch (err) {
|
||||
return response['data'];
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
static Future<UserInfo> getUserInfo(Map<String, String> params) async {
|
||||
var response = await NetUtils.get(Api.GET_USER_INFO, params);
|
||||
print(response);
|
||||
UserInfo userInfo = UserInfo.fromJson(response['data']);
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
// 验证登陆
|
||||
|
||||
static Future<bool> checkLogin() async{
|
||||
static Future<bool> checkLogin() async {
|
||||
var response = await NetUtils.get(Api.CHECK_LOGIN);
|
||||
print('验证登陆:$response');
|
||||
return response['success'];
|
||||
}
|
||||
|
||||
// 退出登陆
|
||||
static Future<bool> logout() async{
|
||||
static Future<bool> logout() async {
|
||||
var response = await NetUtils.get(Api.LOGOUT);
|
||||
print('退出登陆 $response');
|
||||
return response['success'];
|
||||
|
@ -17,12 +17,12 @@ class NetUtils {
|
||||
var response;
|
||||
|
||||
// 设置代理 便于本地 charles 抓包
|
||||
// (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
|
||||
// (HttpClient client) {
|
||||
// client.findProxy = (uri) {
|
||||
// return "PROXY 30.10.26.193:8888";
|
||||
// };
|
||||
// };
|
||||
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
|
||||
(HttpClient client) {
|
||||
client.findProxy = (uri) {
|
||||
return "PROXY 30.10.29.190:8888";
|
||||
};
|
||||
};
|
||||
|
||||
Directory documentsDir = await getApplicationDocumentsDirectory();
|
||||
String documentsPath = documentsDir.path;
|
||||
|
@ -32,8 +32,7 @@ class MainPage extends StatelessWidget {
|
||||
'https://hbimg.huabanimg.com/9bfa0fad3b1284d652d370fa0a8155e1222c62c0bf9d-YjG0Vt_fw658',
|
||||
scale: 15.0,
|
||||
),
|
||||
)
|
||||
),
|
||||
)),
|
||||
centerTitle: true,
|
||||
title: TabLayout(),
|
||||
actions: <Widget>[
|
||||
@ -44,6 +43,20 @@ class MainPage extends StatelessWidget {
|
||||
})
|
||||
],
|
||||
),
|
||||
drawer: Drawer(
|
||||
child: new ListView(
|
||||
children: <Widget>[
|
||||
new ListTile(
|
||||
title: new Text("欢迎"),
|
||||
),
|
||||
new Divider(),
|
||||
new ListTile(
|
||||
title: new Text("设置"),
|
||||
trailing: new Icon(Icons.settings),
|
||||
onTap: () {}),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: TabBarViewLayout(),
|
||||
// drawer: Drawer(
|
||||
// child: MainLeftPage(),
|
||||
@ -63,12 +76,9 @@ class TabLayout extends StatelessWidget {
|
||||
return TabBar(
|
||||
isScrollable: true,
|
||||
//labelPadding: EdgeInsets.all(12.0),
|
||||
labelPadding: EdgeInsets.only(top: 12.0,left: 12.0,right:12.0),
|
||||
labelPadding: EdgeInsets.only(top: 12.0, left: 12.0, right: 12.0),
|
||||
indicatorSize: TabBarIndicatorSize.label,
|
||||
tabs: _allPages
|
||||
.map((_Page page) =>
|
||||
Tab(text: page.labelId))
|
||||
.toList(),
|
||||
tabs: _allPages.map((_Page page) => Tab(text: page.labelId)).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:event_bus/event_bus.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
import 'package:flutter_go/utils/data_utils.dart';
|
||||
import 'package:flutter_go/views/home.dart';
|
||||
import 'package:flutter_go/event/event_bus.dart';
|
||||
import 'package:flutter_go/event/event_model.dart';
|
||||
|
||||
import 'package:flutter_go/model/user_info_cache.dart';
|
||||
import 'package:flutter_go/routers/application.dart';
|
||||
import 'package:flutter_go/routers/routers.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
@override
|
||||
@ -11,6 +18,11 @@ class LoginPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
_LoginPageState() {
|
||||
final eventBus = new EventBus();
|
||||
ApplicationEvent.event = eventBus;
|
||||
}
|
||||
|
||||
// 利用FocusNode和_focusScopeNode来控制焦点 可以通过FocusNode.of(context)来获取widget树中默认的_focusScopeNode
|
||||
FocusNode _emailFocusNode = new FocusNode();
|
||||
FocusNode _passwordFocusNode = new FocusNode();
|
||||
@ -47,27 +59,53 @@ class _LoginPageState extends State<LoginPage> {
|
||||
} catch (err) {
|
||||
print('读取用户本地存储的用户信息出错 $err');
|
||||
}
|
||||
|
||||
ApplicationEvent.event.on<UserGithubOAuthEvent>().listen((event) {
|
||||
if (event.isSuccess == true) {
|
||||
print('请求接口');
|
||||
// oAuth 认证成功
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
DataUtils.getUserInfo({'loginName': event.loginName}).then((result) {
|
||||
print(result);
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(builder: (context) => AppPage()),
|
||||
(route) => route == null);
|
||||
}).catchError((onError) {
|
||||
print('获取身份信息 error:::$onError');
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
print('这是接受到的 event ${event.isSuccess} ${event.loginName}');
|
||||
// _getList();
|
||||
});
|
||||
}
|
||||
|
||||
// 创建登录界面的TextForm
|
||||
Widget buildSignInTextForm() {
|
||||
return new Container(
|
||||
decoration: new BoxDecoration(
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
height: 190,
|
||||
// * Flutter提供了一个Form widget,它可以对输入框进行分组,然后进行一些统一操作,如输入内容校验、输入框重置以及输入内容保存。
|
||||
child: new Form(
|
||||
child: Form(
|
||||
key: _signInFormKey,
|
||||
child: new Column(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 25, right: 25, top: 20, bottom: 20),
|
||||
child: new TextFormField(
|
||||
child: TextFormField(
|
||||
controller: _userNameEditingController,
|
||||
//关联焦点
|
||||
focusNode: _emailFocusNode,
|
||||
@ -78,14 +116,14 @@ class _LoginPageState extends State<LoginPage> {
|
||||
_focusScopeNode.requestFocus(_passwordFocusNode);
|
||||
},
|
||||
|
||||
decoration: new InputDecoration(
|
||||
icon: new Icon(
|
||||
decoration: InputDecoration(
|
||||
icon: Icon(
|
||||
Icons.email,
|
||||
color: Colors.black,
|
||||
),
|
||||
hintText: "Github 登录名",
|
||||
border: InputBorder.none),
|
||||
style: new TextStyle(fontSize: 16, color: Colors.black),
|
||||
style: TextStyle(fontSize: 16, color: Colors.black),
|
||||
//验证
|
||||
validator: (value) {
|
||||
if (value.isEmpty) {
|
||||
@ -100,7 +138,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
new Container(
|
||||
Container(
|
||||
height: 1,
|
||||
width: MediaQuery.of(context).size.width * 0.75,
|
||||
color: Colors.grey[400],
|
||||
@ -108,18 +146,18 @@ class _LoginPageState extends State<LoginPage> {
|
||||
Flexible(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 25, right: 25, top: 20),
|
||||
child: new TextFormField(
|
||||
child: TextFormField(
|
||||
controller: _passwordEditingController,
|
||||
focusNode: _passwordFocusNode,
|
||||
decoration: new InputDecoration(
|
||||
icon: new Icon(
|
||||
decoration: InputDecoration(
|
||||
icon: Icon(
|
||||
Icons.lock,
|
||||
color: Colors.black,
|
||||
),
|
||||
hintText: "Github 登录密码",
|
||||
border: InputBorder.none,
|
||||
suffixIcon: new IconButton(
|
||||
icon: new Icon(
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(
|
||||
Icons.remove_red_eye,
|
||||
color: Colors.black,
|
||||
),
|
||||
@ -128,7 +166,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
//输入密码,需要用*****显示
|
||||
obscureText: !isShowPassWord,
|
||||
style: new TextStyle(fontSize: 16, color: Colors.black),
|
||||
style: TextStyle(fontSize: 16, color: Colors.black),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "密码不可为空!";
|
||||
@ -142,7 +180,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
new Container(
|
||||
Container(
|
||||
height: 1,
|
||||
width: MediaQuery.of(context).size.width * 0.75,
|
||||
color: Colors.grey[400],
|
||||
@ -154,15 +192,15 @@ class _LoginPageState extends State<LoginPage> {
|
||||
}
|
||||
|
||||
Widget buildSignInButton() {
|
||||
return new GestureDetector(
|
||||
child: new Container(
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 42, right: 42, top: 10, bottom: 10),
|
||||
decoration: new BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(5)),
|
||||
color: Theme.of(context).primaryColor),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
"LOGIN",
|
||||
style: new TextStyle(fontSize: 25, color: Colors.white),
|
||||
style: TextStyle(fontSize: 25, color: Colors.white),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
@ -186,7 +224,9 @@ class _LoginPageState extends State<LoginPage> {
|
||||
});
|
||||
DataUtils.doLogin({'username': username, 'password': password})
|
||||
.then((result) {
|
||||
print(result);
|
||||
if(result.runtimeType == String){
|
||||
throw result;
|
||||
}
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
@ -198,20 +238,28 @@ class _LoginPageState extends State<LoginPage> {
|
||||
.then((value) {
|
||||
// print('存储成功:$value');
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
new MaterialPageRoute(builder: (context) => AppPage()),
|
||||
MaterialPageRoute(builder: (context) => AppPage()),
|
||||
(route) => route == null);
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
new MaterialPageRoute(builder: (context) => AppPage()),
|
||||
MaterialPageRoute(builder: (context) => AppPage()),
|
||||
(route) => route == null);
|
||||
}
|
||||
}).catchError((onError) {
|
||||
print(onError);
|
||||
}).catchError((errorMsg) {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
Fluttertoast.showToast(
|
||||
msg: errorMsg.toString(),
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
timeInSecForIos: 1,
|
||||
backgroundColor: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
fontSize: 16.0
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -275,7 +323,27 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
buildSignInTextForm(),
|
||||
buildSignInButton(),
|
||||
SizedBox(height: 35.0),
|
||||
SizedBox(height: 15.0),
|
||||
new Container(
|
||||
height: 1,
|
||||
width: MediaQuery.of(context).size.width * 0.75,
|
||||
color: Colors.grey[400],
|
||||
margin: const EdgeInsets.only(bottom: 10.0),
|
||||
),
|
||||
FlatButton(
|
||||
child: Text(
|
||||
'Github OAuth 认证',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryColor,
|
||||
decoration: TextDecoration.underline),
|
||||
),
|
||||
onPressed: () {
|
||||
// _launchURL('https://github.com/login/oauth/authorize?client_id=cfe4795e76382ae8a5bd&scope=user,public_repo');
|
||||
|
||||
Application.router.navigateTo(context,
|
||||
'${Routes.webViewPage}?title=Github&url=${Uri.encodeComponent("https://github.com/login/oauth/authorize?client_id=cfe4795e76382ae8a5bd&scope=user,public_repo")}');
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
|
@ -11,6 +11,7 @@ import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
|
||||
import 'package:flutter_go/model/collection.dart';
|
||||
import 'package:flutter_go/event/event_bus.dart';
|
||||
import 'package:flutter_go/event/event_model.dart';
|
||||
import 'package:flutter_go/api/api.dart';
|
||||
|
||||
class WebViewPage extends StatefulWidget {
|
||||
final String url;
|
||||
@ -21,6 +22,7 @@ class WebViewPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _WebViewPageState extends State<WebViewPage> {
|
||||
final flutterWebviewPlugin = new FlutterWebviewPlugin();
|
||||
bool _hasCollected = false;
|
||||
String _router = '';
|
||||
var _collectionIcons;
|
||||
@ -30,6 +32,24 @@ class _WebViewPageState extends State<WebViewPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
flutterWebviewPlugin.onUrlChanged.listen((String url) {
|
||||
print('url change:$url');
|
||||
if (url.indexOf('${Api.RedirectIp}loginSuccess') == 0) {
|
||||
String loginName = url.substring(url.indexOf('=') + 1);
|
||||
if (ApplicationEvent.event != null) {
|
||||
ApplicationEvent.event.fire(UserGithubOAuthEvent(loginName, true));
|
||||
}
|
||||
flutterWebviewPlugin.close();
|
||||
// 验证成功
|
||||
} else if (url.indexOf('${Api.RedirectIp}loginFail') == 0) {
|
||||
// 验证失败
|
||||
if (ApplicationEvent.event != null) {
|
||||
ApplicationEvent.event.fire(UserGithubOAuthEvent('', true));
|
||||
}
|
||||
flutterWebviewPlugin.close();
|
||||
}
|
||||
// if(url == '${Api.RedirectIp}loginSuccess')
|
||||
});
|
||||
_collectionControl
|
||||
.getRouterByName(Uri.encodeComponent(widget.title.trim()))
|
||||
.then((list) {
|
||||
|
@ -144,6 +144,13 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
fluttertoast:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fluttertoast
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -29,6 +29,7 @@ dependencies:
|
||||
shared_preferences: ^0.4.3
|
||||
flutter_spinkit: "^3.1.0"
|
||||
path_provider: ^1.0.0
|
||||
fluttertoast: ^3.1.0
|
||||
dio: ^2.0.15
|
||||
flutter_webview_plugin: ^0.3.4
|
||||
cookie_jar: ^1.0.0
|
||||
|
Reference in New Issue
Block a user