I need to understand how to authenticate a REST client (could be Paw, could be an android app, an iOs app using AFNetworking with jHipster and I think, more in general, with
First of all, do not use HTTP session authentication for mobile apps.
On the other hand, Oauth2 or JWT works fine with mobile apps. The basic idea behind them is to get a token from Jhipster to mobile the token has an expiry time. In that time you can use the token to access any REST API of Jhipster to access data.
Below I am showing the code snippet of how I was using the Jhipster rest API in my angularjs based ionic app. I hope it gives the idea of what you need to do.
uncomment cors in application.yml inside jhipster
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
To access REST API with Oauth2 authentication in ionic you must first get the token in the ionic app by
$http({
method: "post",
url: "http://192.168.0.4:8085/[Your app name]/oauth/token",
data: "username=admin&password=admin&grant_type=password&scope=read write&client_secret=my-secret-token-to-change-in-production&client_id=auth2Sconnectapp",
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Authorization': 'Basic ' + 'YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24='
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
Here "YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24=" is equal to (clientId + ":" + clientSecret)--all base64-encoded
The above $http if successful will give you this JSON which contains token and it's expiry time
{
"access_token": "2ce14f67-e91b-411e-89fa-8169e11a1c04",
"token_type": "bearer",
"refresh_token": "37baee3c-f4fe-4340-8997-8d7849821d00",
"expires_in": 525,
"scope": "read write"
}
Take notice of "access_token" and "token_type" if you want to access any API this is what you have to use. We send the token with API to access data until the token expires then we either refresh it or access for a new one.
For example
$http({
method: "get",
url: "http://192.168.0.4:8085/auth-2-sconnect/api/countries",
withCredentials: true,
headers: {
'Authorization':' [token_type] + [space] + [access_token] '
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
Here a summarisation of how I implemented the solution. It’s real swift code, but please take it as pseudocode, as it might be incorrect.
make a call to whatever method you need to call, passing in such method a callback (block, or equivalent) for the success and one for the failure
func action(
URLString:String,
method:Method,
encoding:Encoding = .JSON,
parameters:[String : AnyObject]?,
success:(statusCode:Int, responseObject:AnyObject)->Void,
failure:(statusCode:Int, error:NSError)->Void
)
Inside the method es. /events
you handle a particular case of failure, which is when the status code is 401.
if(r!.statusCode==ResponseCodes.HTTP_UNAUTHORIZED.rawValue){
loginAndAction(URLString, method: method, encoding: encoding, parameters: parameters, success: success, failure: failure)
}else{
failure(statusCode: response.response!.statusCode, error:response.result.error!)
}
In this particular case, instead of returning back the result and calling the failure callback, you call a login() method which, after the necessary parameters, accept the original success()
callback
func loginAndAction(
URLString:String,
method:Method,
encoding: Encoding,
parameters:[String:AnyObject]?,
success:(statusCode:Int, responseObject:AnyObject)->Void,
failure:(statusCode:Int, error:NSError)->Void
)->Void
if the authentication succeeds
var d:[String:AnyObject] = response.result.value as! [String:AnyObject]
self.authToken = d["access_token"] as! String
action(URLString, method: method,encoding:encoding, parameters: parameters, success: success, failure: failure)
at this point the method action could use a proper working token.
This should happen only once a day (based on the token expiration), and it is a mechanism appliable to the oauth2 refresh_token
call.