我正在尝试为我的AngularJS应用程序编写HTTP拦截器来处理身份验证.
这段代码有效,但我担心手动注入服务,因为我认为Angular应该自动处理:
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push(function ($location, $injector) {
return {
'request': function (config) {
//injected manually to get around circular dependency problem.
var AuthService = $injector.get('AuthService');
console.log(AuthService);
console.log('in request interceptor');
if (!AuthService.isAuthenticated() && $location.path != '/login') {
console.log('user is not logged in.');
$location.path('/login');
}
return config;
}
};
})
}]);
Run Code Online (Sandbox Code Playgroud)
我开始做的事情,但遇到循环依赖问题:
app.config(function ($provide, $httpProvider) {
$provide.factory('HttpInterceptor', function ($q, $location, AuthService) {
return {
'request': function (config) {
console.log('in request interceptor.');
if (!AuthService.isAuthenticated() && $location.path != '/login') {
console.log('user …Run Code Online (Sandbox Code Playgroud) 我刚刚开始为我的AngularJS应用程序编写测试,我在Jasmine中这样做.
以下是相关的代码段
ClientController:
'use strict';
adminConsoleApp.controller('ClientController',
function ClientController($scope, Client) {
//Get list of clients
$scope.clients = Client.query(function () {
//preselect first client in array
$scope.selected.client = $scope.clients[0];
});
//necessary for data-binding so that it is accessible in child scopes.
$scope.selected = {};
//Current page
$scope.currentPage = 'start.html';
//For Client nav bar
$scope.clientNavItems = [
{destination: 'features.html', title: 'Features'},
];
//Set current page
$scope.setCurrent = function (title, destination) {
if (destination !== '') {
$scope.currentPage = destination;
}
};
//Return path …Run Code Online (Sandbox Code Playgroud) 在我开始之前,我要说的是我找到的最接近的答案就在这里,但说实话,我并不真正理解那里发生了什么.
我正在使用Struts2 + Spring Security 2.06与自定义身份验证提供程序和访问决策管理器来消除对"ROLE_"前缀的需求.
我的applicationContext-security.xml看起来像这样:
<beans:bean id="customAuthenticationProvider"
class="com.test.testconsole.security.CustomAuthenticationProvider">
<beans:property name="userManagementService" ref="userManagementService"/>
<custom-authentication-provider/>
</beans:bean>
<!--Customize Spring Security's access decision manager to remove need for "ROLE_" prefix-->
<beans:bean
id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:ref bean="roleVoter"/>
<beans:ref bean="authenticatedVoter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean
id="roleVoter"
class="org.springframework.security.vote.RoleVoter">
<beans:property name="rolePrefix" value=""/>
</beans:bean>
<beans:bean
id="authenticatedVoter"
class="org.springframework.security.vote.AuthenticatedVoter">
</beans:bean>
<global-method-security secured-annotations="enabled" access-decision-manager-ref="accessDecisionManager"/>
Run Code Online (Sandbox Code Playgroud)
我的web.xml的相关部分:
<!--Spring Security-->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<!--Has to be placed _Before_ the struts2 filter-mapping-->
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern> …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring Security来保护Struts2 Web应用程序.由于项目限制,我使用的是Spring Security 2.06.
我的团队构建了一个自定义用户管理API,用于在接收用户名和密码参数后对用户进行身份验证,并返回包含角色列表和其他属性(如电子邮件,名称等)的自定义用户对象.
根据我的理解,典型的Spring Security用例使用默认的UserDetailsService来检索UserDetails对象; 此对象将包含(以及其他内容)框架将用于对用户进行身份验证的密码字段.
在我的情况下,我想让我们的自定义API执行身份验证,然后返回包含角色和其他属性(电子邮件等)的自定义UserDetails对象.
经过一些研究,我发现我可以通过AuthenticationProvider的自定义实现来实现这一点.我也有UserDetailsService和UserDetails的自定义实现.
我的问题是我真的不明白我应该在CustomAuthenticationProvider中返回什么.我在这里使用自定义UserDetailsService对象吗?甚至需要吗?对不起,我真的很困惑.
CustomAuthenticationProvider:
public class CustomAuthenticationProvider implements AuthenticationProvider {
private Logger logger = Logger.getLogger(CustomAuthenticationProvider.class);
private UserDetailsService userDetailsService; //what am i supposed to do with this?
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
String username = String.valueOf(auth.getPrincipal());
String password = String.valueOf(auth.getCredentials());
logger.info("username:" + username);
logger.info("password:" + password);
/* what should happen here? */
return null; //what do i return?
}
@Override
public boolean supports(Class aClass) …Run Code Online (Sandbox Code Playgroud) 我正在使用AngularJS v1.2.4.
我在Angular发送预检OPTIONS调用时遇到问题(Chrome将OPTIONS调用显示为'已取消')并通过以下方式解决:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
Run Code Online (Sandbox Code Playgroud)
这适用于我所有的资源调用,一切都很好.
现在我正在尝试实现身份验证,以及一个使用用户凭据向我的服务器发送POST请求的登录页面.我看到之前遇到的问题,但$资源调用仍然正常.
真正令人沮丧的是问题是间歇性地发生的; 我将更改标题周围的一些选项,然后它会工作一点,并在没有任何代码更改的情况下再次停止工作.
我的服务器配置为CORS,并且可以与curl和其他REST客户端一起使用.这是一个例子:
curl -X OPTIONS -ik 'https://localhost:3001/authenticate' -H "Origin: https://localhost:8001"
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
content-length: 2
cache-control: no-cache
access-control-allow-origin: *
access-control-max-age: 86400
access-control-allow-methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
access-control-allow-headers: Authorization, Content-Type, If-None-Match, Access-Control-Allow-Headers, Content-Type
access-control-expose-headers: WWW-Authenticate, Server-Authorization
set-cookie: session=Fe26.2**94705d49717d1273197ae86ce6661775627d7c6066547b757118c90c056e393b*2KYqhATojPoQhpB2OwhDwg*W9GsJjK-F-UPqIIHTBHHZx1RXipo0zvr97_LtTLMscRkKqLqr8H6WiGd2kczVwL5M25FBlB1su0JZllq2QB-9w**5510263d744a9d5dc879a89b314f6379d17a39610d70017d60acef01fa63ec10*pkC9zEOJTY_skGhb4corYRGkUNGJUr8m5O1US2YhaRE; Secure; Path=/
Date: Wed, 18 Dec 2013 23:35:56 GMT
Connection: keep-alive
Run Code Online (Sandbox Code Playgroud)
这是$ http.post调用:
var authRequest = $http.post('https://' + $location.host() + ':3001/authenticate', {email: email, password: password});
Run Code Online (Sandbox Code Playgroud)
当我的应用程序调用工作时,这就是OPTIONS请求的样子:

当它不起作用时,这是OPTIONS请求: …
我有一个项目列表,点击其中一个项目后,会显示一个模态对话框供用户进行一些更改,然后单击"关闭"或"保存更改".
问题在于,假设用户进行了一些更改并点击了"关闭",这些更改将反映在视图绑定的模型中,因为数据绑定是即时的.
我的问题是,我如何推迟更新并仅在单击"保存更改"时执行绑定,或者如果单击"取消"则以某种方式忘记更改.
我的模态对话框的代码如下:
<div ui-modal class="fade static" ng-model="modalShown" id="myModal" data-backdrop="static">
<div class="modal-header">
<button type="button" class="close" ng-click="closeModal()" aria-hidden="true">×</button>
<h3>{{selectedClientFeature.feature.type}}</h3>
</div>
<div class="modal-body">
<ul class="unstyled columnlist">
<li ng-repeat="country in countriesForEdit">
<input type="checkbox" ng-model="country.selected"> {{country.name}}
</li>
</ul>
</div>
<div class="modal-footer">
<a ng-click="closeModal()" class="btn">Close</a>
<a ng-click="saveChanges()" class="btn btn-primary">Save changes</a>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
谢谢,肖恩
今天,我将Redis集成到我的node.js应用程序中,并将其用作会话存储。基本上,在身份验证成功后,我会将相应的用户对象存储在Redis中。
身份验证后收到HTTP请求时,我尝试使用哈希从Redis检索用户对象。如果检索成功,则意味着用户已登录并且可以满足请求。
将用户对象存储在Redis中和进行检索的操作发生在两个不同的文件中,因此每个文件中都有一个Redis客户端。
问题1:可以有两个Redis客户端,每个文件一个吗?还是应该仅实例化一个客户端,并在应用程序的所有区域中使用它?
问题2:node-redis库是否提供一种显示已连接客户端列表的方法?如果是这样,我将能够遍历该列表,并在服务器关闭时为它们中的每一个调用client.quit()。
顺便说一下,这就是我实现服务器“正常关机”的方式:
//Gracefully shutdown and perform clean-up when kill signal is received
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
function cleanup() {
server.stop(function() {
//todo: quit all connected redis clients
console.log('Server stopped.');
//exit the process
process.exit();
});
};
Run Code Online (Sandbox Code Playgroud) 注意:我还在AngularJS邮件列表上发布了这个问题:https://groups.google.com/forum/#!topic / angular/UUC8_pZsdn2U
大家好,
我正在构建我的第一个AngularJS应用程序,并且我不熟悉Javascript,所以任何指导都将非常感谢:)
我的应用程序有两个控制器,ClientController和CountryController.在CountryController中,我正在从使用$ resource对象的CountryService中检索国家列表.这很好,但我希望能够与ClientController共享国家/地区列表.经过一些研究,我读到我应该使用CountryService来存储数据并将该服务注入两个控制器.
这是我以前的代码:
CountryService:
services.factory('CountryService', function($resource) {
return $resource('http://localhost:port/restwrapper/client.json', {port: ':8080'});
});
Run Code Online (Sandbox Code Playgroud)
CountryController:
//Get list of countries
//inherently async query using deferred promise
$scope.countries = CountryService.query(function(result){
//preselected first entry as default
$scope.selected.country = $scope.countries[0];
});
Run Code Online (Sandbox Code Playgroud)
在我改变之后,它们看起来像这样:
CountryService:
services.factory('CountryService', function($resource) {
var countryService = {};
var data;
var resource = $resource('http://localhost:port/restwrapper/country.json', {port: ':8080'});
var countries = function() {
data = resource.query();
return data;
}
return {
getCountries: function() {
if(data) {
console.log("returning cached …Run Code Online (Sandbox Code Playgroud) 我有一个控制器使用angular-ui/bootstrap中的Dialog:
function ClientFeatureController($dialog, $scope, ClientFeature, Country, FeatureService) {
//Get list of client features for selected client (that is set in ClientController)
$scope.clientFeatures = ClientFeature.query({clientId: $scope.selected.client.id}, function () {
console.log('getting clientfeatures for clientid: ' + $scope.selected.client.id);
console.log($scope.clientFeatures);
});
//Selected ClientFeature
$scope.selectedClientFeature = {};
/**
* Edit selected clientFeature.
* @param clientFeature
*/
$scope.editClientFeature = function (clientFeature) {
//set selectedClientFeature for data binding
$scope.selectedClientFeature = clientFeature;
var dialogOpts = {
templateUrl: 'partials/clients/dialogs/clientfeature-edit.html',
controller: 'EditClientFeatureController',
resolve: {selectedClientFeature: function () {
return clientFeature;
} …Run Code Online (Sandbox Code Playgroud) javascript ×7
angularjs ×6
jasmine ×2
java ×2
spring ×2
angular-ui ×1
cors ×1
http ×1
node-redis ×1
node.js ×1
redis ×1
struts2 ×1
tdd ×1
testing ×1
unit-testing ×1