【发布时间】:2014-09-22 21:27:05
【问题描述】:
我想在我的 Go 应用程序上设置一个带有令牌的身份验证系统,该应用程序使用 AngularJS 前端。
我正在寻找有关创建安全系统的所有步骤的建议。这是我的步骤:
我们会考虑一个用户条目已经写入我们的数据库。
1 - 用户想要登录
用户转到提示他登录的网络应用程序的索引。
通过我的 app.yaml 文件,我为 AngularJS 前端声明了带有 dependencies 的 HTML 文件:
application: authtest
version: 1
runtime: go
api_version: go1
handlers:
- url: /
static_files: frontend/index.html
upload: frontend/(.*\.html)
- url: /js
static_dir: frontend/js
- url: /.*
script: _go_app
视觉:
代码:
<form ng-submit="signIn()" ng-controller="signInCtrl">
<input type="email" ng-model="credentials.email" placeholder="Email" name="email">
<input type="password" ng-model="credentials.password" placeholder="Password" name="password">
<input type="submit" value="Sign in">
</form>
用户输入他的凭据,然后点击登录按钮。
2 - 请求服务器
AngularJS 模块代码:
<script>
angular.module('authtest', ['ngCookies'])
.controller('signInCtrl', ['$scope', '$http', '$window', '$cookieStore', '$route', function($scope, $http, $window, $cookieStore, $route){
var credentials = {}
$scope.signIn = function() {
$http.post('/signin', credentials)
.success(function (data, status) {
if(status == 200) {
if(data.Access_token){
//set cookies with tokens
$cookieStore.put('access_token', data.Access_token);
$cookieStore.put('refresh_token', data.Refresh_token);
$route.reload();
}
else {
$window.alert('Wrong credentials, try again.');
}
}
})
.error(function (data, status) {
$window.alert('error: ' + data + '(errorStatus: ' + status + ')');
});
};
}]);
</script>
Angular 模块将表单发布到 /signin 路径,因此 Go 应用程序需要处理它:
package main
import (
"net/http"
"encoding/json"
"fmt"
)
type SignInCredentials struct {
Email string
Password string
}
type Token struct {
Access_token string
Refresh_token string
Id_token string
}
func init() { //I use init() instead of main() because I'm using App Engine.
http.HandleFunc("/signin", SignInHandler)
}
func SignInHandler (w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var c SignInCredentials
err := decoder.Decode(&c)
if err != nil {
panic()
}
var hashPassword = hash(c.Password) //Is it at a good level to hash it ?
if isInDatabase(c.Email, hashPassword) == false {
fmt.Fprintf(w, "") // Really useful ?
return
}
var tokens Token
/**
* The user seems to be well stored in the database, but how
* to manage my tokens ?
*/
response, _ := json.Marshal(tokens)
fmt.Fprintf(w, string(response))
}
显然,hashPassword(p string) 对用户密码进行哈希处理,isInDatabase(e string, p string) 是一个布尔值,用于检查提供的凭据是否存储在我们的数据库中。
- 正如我在代码中所说,我想知道现在是散列用户密码的 好时机,还是在 客户端 中散列它?
- 如果用户不在数据库中,打印一个零车字符串真的很有用,或者我可以返回函数吗?
- 这里的主要问题是如何管理我的令牌?我经常看到token主要由
access_token、refresh_token和id_token组成。我也知道access_token的使用时间有限(例如当前会话,3600 秒),我们使用refresh_token来获得一个全新的access_token。但是如何生成和存储呢?
3 - 使用 AngularJS 处理响应
正如已经用 AngularJS 模块代码编写的那样,当用户通过良好的身份验证时,我们使用提供的 tokens 设置 cookie。这是一个好方法吗?我也想知道如何在我的系统中防止XSRF (CSRF) 攻击?
感谢您未来的回答和建议。
【问题讨论】:
标签: angularjs authentication go token