使用Go和AngularJS进行用户身份验证
我想在我的Go应用程序上使用令牌建立一个身份验证系统,该应用程序使用AngularJS前端 我要找的是关于创建安全系统的所有步骤的建议。以下是我的步骤: 我们会考虑一个用户条目已经写入我们的数据库 1-用户想要登录 用户转到web应用程序的索引,该索引提示用户登录 使用我的app.yaml文件,我为AngularJS前端声明了我的HTML文件,其中包含依赖项:使用Go和AngularJS进行用户身份验证,angularjs,authentication,go,token,Angularjs,Authentication,Go,Token,我想在我的Go应用程序上使用令牌建立一个身份验证系统,该应用程序使用AngularJS前端 我要找的是关于创建安全系统的所有步骤的建议。以下是我的步骤: 我们会考虑一个用户条目已经写入我们的数据库 1-用户想要登录 用户转到web应用程序的索引,该索引提示用户登录 使用我的app.yaml文件,我为AngularJS前端声明了我的HTML文件,其中包含依赖项: application: authtest version: 1 runtime: go api_version: go1 handl
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>
代码:
<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>
显然,hashPassword(p字符串)
对用户密码进行哈希运算,isindabase(e字符串,p字符串)
是一个布尔值,用于检查提供的凭据是否存储在我们的数据库中
- 正如我在代码中所说的,我想知道现在是对用户密码进行哈希运算的好时机,还是在客户端进行哈希运算李>
- 如果用户不在数据库中,则打印一个零car字符串非常有用,或者我可以返回该函数吗李>
- 这里的主要问题是如何管理我的代币?我经常看到令牌主要由
、access\u-token
和refresh\u-token
组成。我还知道id\u-token
的使用时间有限(例如当前会话,ot 3600秒),我们使用access\u token
来获得新的refresh\u token
。但是如何生成和存储它呢access\u token
- 这里的主要问题是如何管理我的代币?我经常看到令牌主要由
<form name="loginform" class="uk-form" ng-submit="login()">
<fieldset data-uk-margin>
<legend><h2>Login</h2></legend>
<div class="uk-form-row">
<input class="uk-form-large" type="text" ng-model="cred.user" placeholder="Username" required>
</div>
<div class="uk-form-row">
<input class="uk-form-large" type="password" ng-model="cred.password" placeholder="Password" required>
</div>
<div class="uk-form-row">
<button ng-disabled="loginform.$invalid" class="uk-button uk-button-large" type="submit">Login</button>
</div>
</fieldset>
</form>
控制器需要一个200 http状态码(除非身份验证成功,否则后端不应响应),如果服务器响应的不是200,则路由将再次更改为登录页面
棘手的部分是维护身份验证状态的检查
我实现身份验证系统的方法是通过以下方式向路由对象添加自定义属性(如指南,但没有角色系统):
App.controller('LoginCtrl', function ($rootScope, $scope, $location, $window, authService) {
$scope.cred = {}
$scope.login = function () {
if ($scope.loginform.$valid) {
authService.auth(this.cred, function (stat) {
if (stat === 200) {
$rootScope.loginStatus = authService.isLoggedIn();
$location.path('/test');
} else {
....
$location.path('/login');
}
});
$scope.cred = {}
$scope.loginform.$setPristine();
}
};
$window.document.title = 'Admin Login';
});
App.js
然后,每当一条路由被请求时,我就有这个函数来评估该路由是否需要特定的特权/身份验证才能进入该路由(ofc这并不意味着你的路由是安全的,它只是意味着除非js文件被动态修改,否则你的普通joe将无法查看路由)
App.js
使用$routeChangeStart
传递的函数调用我调用的authService
服务中的另一个函数,如下所示
authService.js
现在,每当需要特定角色或身份验证的路由需要评估并从服务器获取200状态代码时,否则身份验证状态将设置为false
,直到用户再次进行身份验证。最后,如果前端只依赖于1%的身份验证过程,那么整个身份验证系统就会变得冗余
编辑 CSRF风险和会话管理 在CSRF的例子中,我使用了一个名为的框架,这个框架提供了一种现成的CSRF避免机制,您只需要指定外派日期和令牌的加密 当涉及到登录会话时,服务器应该管理作为cookie存储在客户端的加密会话,当然我不建议您实现这一点,因为这是非常危险的,并且可能以错误的方式实现。同样,Beego提供了一个很好的功能,允许您以自己的方式管理和加密会话 我希望这有助于回答你的问题,祝你好运
App.controller('LoginCtrl', function ($rootScope, $scope, $location, $window, authService) {
$scope.cred = {}
$scope.login = function () {
if ($scope.loginform.$valid) {
authService.auth(this.cred, function (stat) {
if (stat === 200) {
$rootScope.loginStatus = authService.isLoggedIn();
$location.path('/test');
} else {
....
$location.path('/login');
}
});
$scope.cred = {}
$scope.loginform.$setPristine();
}
};
$window.document.title = 'Admin Login';
});
...
$routeProvider.when('/login', {
templateUrl: '/content/...',
controller: 'Ctrl1',
requireLogin: false
}).when('/logout', {
resolve: {
logout: function ($location, $rootScope, authService) {
authService.logout(function (s) {
if (s === 200) {
$rootScope.loginStatus = authService.isLoggedIn();
$location.path('/test');
} else {
....
}
});
}
},
requireLogin: true
}).when('/metaconfig', {
templateUrl: '/content/...',
controller: 'Ctrl2',
requireLogin: true
...
angular.module('App', ['ngCookies', 'ngRoute'])
.config(function{...}).run(function ($rootScope, ..., $location, authService) {
$rootScope.loginStatus = false;
authService.authCheck();
$rootScope.$on('$routeChangeStart', function (event, next, current) {
if (next.requireLogin) {
if (!authService.isLoggedIn()) {
$location.path('/login');
event.preventDefault();
}
}
});
'use strict';
App.service('authService', function ($rootScope, $log, $http, $q) {
var userIsAuthenticated = false;
this.auth = function (up, cb) {
$http({method: 'POST', url: '/api/login', data: up}).
success(function (data, status, headers, config) {
if (status === 200) {
userIsAuthenticated = true;
}
cb(status)
}).
error(function (data, status, headers, config) {
userIsAuthenticated = false;
cb(status)
});
};
this.authCheck = function () {
$http({method: 'PUT', url: '/api/login' }).
success(function (data, status, headers, config) {
if (status === 200) {
userIsAuthenticated = true;
} else {
userIsAuthenticated = false;
}
$rootScope.loginStatus = userIsAuthenticated;
}).
error(function (data, status, headers, config) {
userIsAuthenticated = false;
$rootScope.loginStatus = userIsAuthenticated;
});
};
this.isLoggedIn = function () {
return userIsAuthenticated;
};
this.logout = function (cb) {
$http({ method: 'DELETE', url: '/api/logout' }).
success(function (data, status, headers, config) {
userIsAuthenticated = false;
cb(status)
}).
error(function (data, status, headers, config) {
userIsAuthenticated = false;
cb(status)
});
};
});