ApiRTC token authentication - javascript

I am trying to use token authentication with no success. I am wondering if anyone succeed in doing so, as the official ApiRTC documentation is weak on that topic.
1) I have activated secret key below from - Credentials screen
2) For token validation I have setup a service from API - Token authentication screen
3) I have the below code to create the user agent
function createUserAgent(token) {
ua = new apiRTC.UserAgent({
uri: 'token:' + token
});
ua.register({
id : useragentId
}).then(uaRegistered)
.catch(function (error) {
console.log("Registration error");
});
}
function uaRegistered(session) {
console.log("Registration OK");
}
4) This initializes a request to below address. And it fails with HTTP 401
GET https://cloud.apizee.com/api/v2/checkToken?token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhNWQxN2M1ZTVjOWZkYmRiNDJhYTgzMTJlMWQxMmEwYiIsImF1ZCI6ImFwaVJUQyIsImp0aSI6ImE5ZjU4NmNlLTcxMDctNDgxMS04ODYwLTQ5MjY4ODY2NjhiYiIsImlhdCI6MTU1OTg5OTA5MSwiZXhwIjoxNTU5OTAyNjkxLCJncmFudHMiOnsiaWRlbnRpdHkiOiJjbGk5OTQxOTgxNTgifX0.ZfQs_HgUXOWhCAlXB6fTMKhbT-pFslb9MK_JvXu2U5A 401 (Unauthorized)
5) I have also seen that no requests are made to my token validation service.
Thanks
edit: updates according to the answer
function createUserAgent(token) {
apiRTC.setLogLevel(apiRTC.LOG_LEVEL_DEBUG);
var registerInformation = {};
registerInformation.id = useragentId;
registerInformation.token = token;
ua = new apiRTC.UserAgent({
uri: 'apzkey:a5d17c5e5c9fdbdb42aa8312e1d12a0b'
});
$("#sessionStatus").text("Waiting for register response ");
ua.register(registerInformation).then(uaRegistered)
.catch(function (error) {
debugger;
console.log("Registration error");
$("#sessionStatus").text("Failed to register UA");
});
}
function uaRegistered(session) {
debugger;
console.log("Registration OK");
connectedSession = session;
$("#useragentId").text(useragentId);
$("#sessionUsername").text(session.getUsername());
$("#sessionStatus").text("Connected");
debugger;
}

Thanks for pointing this issue in documentation, we have done a first update for using an external validation service here :
https://dev.apirtc.com/authentication/index
On client side, you need to use following code :
registerInformation.token = "myToken"
ua.register(registerInformation).then(function(session) {
// Save session
connectedSession = session;
}).catch(function(error) {
// error
console.error('User agent registration failed', error);
});
the usage of token in uri is for users authentication on Apizee offers

Related

Use firebase tokens to query an API in a client

I used firebase authentication to secure my ASP.NET CORE api.
I actually store the users in the database my API uses. Note that in my database the google identifiers are the uids generated by the firebase authentication and that the classic identifiers (login + password) are generated in my API.
When the user connects with Google, the token is created in the client(Angular) so I send it to my API (of course I don't store it), I just check if the token is valid and if the id which is contained in the token corresponds to the identifier of one of the users which is stored in my database.
In my client, for google authentification:
async GoogleAuth() {
try {
return new Promise((resolve, reject) => {
signInWithPopup(this.auth, this.provider).then(() => {
this.auth.onAuthStateChanged((user) => {
if (user) {
user
.getIdToken()
.then((idToken) => {
this.sendTokenUserGoogleToAPI(user, idToken)
.then((data: any) => {
localStorage.setItem('token', data.token);
resolve(data);
})
.catch((error) => {
console.log("googleAuth : " + error)
reject(error);
});
})
.catch(() => { });
}
});
});
});
} catch (e) { }
}
For the classic connection (login + password), the data is sent directly to my API and I create a personalized token with the user ID in my backend and I send the token to the client who generates a personalized token to from the token.
In my API, for classic authentication :
[HttpPost]
[ActionName("signin")]
public async Task<ActionResult> SignIn([FromBody] UserLoginViewModel userModel)
{
var user = await _context.Users.FirstOrDefaultAsync(u =>
u.Login == userModel.Login && u.Password == userModel.Password);
if (user == null)
{
_logger.LogWarning("Connection attempt failed.");
return NotFound(new { message = "User or password invalid." });
}
if (user.IsLocked)
{
return new ObjectResult(new { message = "Your account has been blocked." }) { StatusCode = 403 };
}
var token = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(user.UserId);
var login = user.Login;
return Ok(new
{
login,
token
});
}
In my client, when I receive the token from my API
signInWithCustomToken(getAuth(),token)
.then((userCredential) => {
const user = userCredential.user;
console.log(token)
user!.getIdToken(true).then((idToken) => {
localStorage.setItem('token', idToken)
}).catch((error) => {
console.log(error)
})
})
So I'm guessing I shouldn't generate the token in my backend and only return the id to generate the token in the client? I regenerate the token in my client so that the user can access the chat
With my client, is it better that I get the token by querying firebase each time or is it better that I store this token locally to be able to use it in my requests?
For the moment, I store it locally but I think that it can be problematic if the token changes or if an attacker modifies his token because I verify thanks to firebase that the user is connected, if the local token changes, firebase will always say that the user is logged in but in my api the token will not be valid.
The ID token you get from Firebase Authentication is an exp property/claim that shows you until when it's valid. Firebase's own SDKs refresh the token about 5 minutes before it expires, so your code should probably do the same. In fact, if you listen for when the ID token changes (Android web), you don't have to force a refresh yourself and can just piggyback on the work the SDK already does for you.

How to refresh credentials in the AWS JS SDK v3?

I am trying to migrate my V2 application to the V3 SDK and I can't seem to figure out how to refresh the credentials after the following call throws a NotAuthorizedException with "Invalid login token. Token expired: 1615301743 >= 1615108625".
credentials = await cognitoIdentity.send(
new GetIdCommand({
Storage: config,
IdentityPoolId: config.get("IdentityPoolId"),
Logins: {
[`cognito-idp.${awsRegion}.amazonaws.com/${upid}`]: idToken,
},
}),
);
In V2 there was a method called refresh() on the Credentials object which I could call and by doing so refresh the credentials. How to do the same thing with the new API?
The following code sample (Check Use case 4) I've found in the following link:
https://www.npmjs.com/package/amazon-cognito-identity-js
//refreshes credentials using AWS.CognitoIdentity.getCredentialsForIdentity()
AWS.config.credentials.refresh(error => {
if (error) {
console.error(error);
} else {
// Instantiate aws sdk service objects now that the credentials have been updated.
// example: var s3 = new AWS.S3();
console.log('Successfully logged!');
}
});
It works for me when implemented in AWS Lambda. Hope this is what you are looking for.
Regards,
Edit:
I've just tested the following code, it works in my react-js app:
return new Promise((resolve, reject) =>
cognitoUser.authenticateUser(authenticationDetails, {
// If the provided credentials are correct.
onSuccess: function(result) {
var accessToken = result.getAccessToken().getJwtToken();
//POTENTIAL: Region needs to be set if not already set previously elsewhere.
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: IdentityPoolId, // Your identity pool id here.
Logins: {
// Change the key below according to the specific Region your User Pool is in.
`cognito-idp.${awsRegion}.amazonaws.com/${upid}`: result
.getIdToken()
.getJwtToken(),
},
});
//refreshes credentials using AWS.CognitoIdentity.getCredentialsForIdentity()
AWS.config.credentials.refresh(error => {
if (error) {
console.error(error);
} else {
resolve(AWS.config.credentials)
}
});
},
// If the provided credentials are incorrect.
onFailure: function(err) {
console.log(err);
reject(
err.message || JSON.stringify(err)
);
},
})
);

AWS Cognito: Can't get Credentials

i can't get the Credentials for my CognitoIdentity. When the User is successfully authenticated, he needs to get a Identity to access other AWS Services. In my case thats AWS IoT. But for somehow, i can't get any credentials.
This is the Error Message:
Error retrieving credentials: NotAuthorizedException: Access to
Identity 'eu-central-1:XXXXXXXXXX' is
forbidden.
My Code is almost exactly like the Tutorial on Github:
var cognitoUser = new AWSCognito.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
console.log("Logged in");
console.log('access token + ' + result.getAccessToken().getJwtToken());
// window.location.href = "index.html";
AWS.config.region = AWSConfiguration.region;
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: AWSConfiguration.IdPoolId,
Logins : {
'cognito-idp.eu-central-1.amazonaws.com/eu-central-1_XXXX' : result.getIdToken().getJwtToken()
}
});
var cognitoIdentity = new AWS.CognitoIdentity();
AWS.config.credentials.get(function(err, data) {
if (!err) {
console.log('retrieved identity: ' + AWS.config.credentials.identityId);
var params = {
IdentityId: AWS.config.credentials.identityId
};
cognitoIdentity.getCredentialsForIdentity(params, function(err, data) {
if (!err) {
thingShadows.updateWebSocketCredentials(data.credentials.AccessKeyId,
data.credentials.SecretKey,
data.credentials.SessionToken);
}
else {
console.log('error retrieving credentials: ' + err);
}
});
}
else {
console.log('error retrieving identity:' + err);
}
});
}
});
Please note that i skipped not related code.
authenticated users have full access to all AWS services i'm using.
I don't think you need to call cognitoIdentity.getCredentialsForIdentity(). Your IAM keys should be put into the AWS.config.credentials object when you call AWS.config.credentials.get(). You can access them directly in the callback you provide when you call it.
In other words, when you're logging out the retrieved identity: to the console, the credentials object should already have your secret key, access key id, and session token in it.
All of this (give or take a curly brace):
var params = {
IdentityId: AWS.config.credentials.identityId
};
cognitoIdentity.getCredentialsForIdentity(params, function(err, data) {
if (!err) {
thingShadows.updateWebSocketCredentials(data.credentials.AccessKeyId,
data.credentials.SecretKey,
data.credentials.SessionToken);
}
else {
console.log('error retrieving credentials: ' + err);
}
});
Can probably be replaced with something like this:
thingShadows.updateWebSocketCredentials(AWS.config.credentials.accessKeyId,
AWS.config.credentials.secretKey,
AWS.config.credentials.sessionToken);
If you pass in a Logins map with the user pool id and access token in it, the getCredentialsForIdentity() call might succeed; I didn't test it. I haven't yet run into a use case where I needed to use this particular API, and I suspect you don't need it either.
Source: I work on a 100% javascript application that uses both authenticated and unauthenticated Cognito identities. We don't call getCredentialsForIdentity() anywhere, and trying to insert it produced the same error you're getting.

authWithOAuthPopup Error on Web Platform

I am trying to use Firebase's Facebook authentication on a webpage, but I get this error:
Login failed Error: Invalid authentication credentials provided.
at Error (native)
at http://45.55.203.213/js/firebase.js:160:367
at e (http://45.55.203.213/js/firebase.js:140:400)
Here's my Javascript code:
var ref = new Firebase("https://fantasy-smash-bros.firebaseio.com/");
function FBLogin() {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login failed", error);
} else {
loginWithAuthData(authData);
}
});
}
function loginWithAuthData(authData) {
username = authData.facebook.displayName;
avatarURL = authData.facebook.cachedUserProfile.picture.data.url;
userID = authData.facebook.id;
}
function attemptLogin() {
var user = ref.getAuth();
if (user) {
loginWithAuthData(user);
} else {
$("#fb-login").click(function () {
FBLogin();
});
}
}
$(document).ready(function () {
attemptLogin();
});
Note: I have imported firebase.js. Here's a copy of the Javascript I used.
I believe I have setup everything correctly: adding Firebase's callback URL to my Facebook app's whitelist, enabling Facebook authentication on the Firebase app. But I am still stumped on what to do. Any help would be greatly appreciated.

Meteor: Login over DDP and retrieve current user object in seperate Meteor app

First a little background:
I am working on an seperate mobile application that is connected with the main app. The connection is succesfully initiated and I can retrieve all collections, through subscriptions:
Remote = DDP.connect('http://localhost:3000/');
Meteor.users = new Meteor.Collection('users', {
connection: Remote
});
Remote.subscribe('users', true);
Now I want to make sure users can log in through the interface of the second app. After installing the accounts-password and the meteor-ddp-login package, I should be able to authenticate with the main app by using the next piece of code in the client side.
var Remote = DDP.connect('http://localhost:3000/');
DDP.loginWithPassword(Remote, {
username: username
}, password, function(error) {
if (!error) {
console.log(username + " is logged in!");
} else {
console.log(error);
}
});
Well, so far so good. No errors appear and the console logs a success message. Now the question comes:
How can I retrieve the user object of the user who just logged in.
I've set up several publish functions in the main app, but the user data does not become available to the client in the second app (other collections work fine, but Meteor.user() is undefined).
And also: How can I authenticate users who login with Facebook/Google/Twitter
Came across this, I had a similar need recently. Following code works in Meteor version 1.2.0.2
if (Meteor.isClient) {
Meteor.startup(function(){
//Seems that without this, on page refresh, it doesn't work.
//COMMENT: Ideally this should not be needed if the core takes care of this use case of a different connection for Accounts
//hack block 1***********
var token = Accounts._storedLoginToken();
if(token) {
Meteor.loginWithToken(token, function(err){
// this is going to throw error if we logged out
if(err)
console.log(err);
else
console.log('loginWithToken');
});//loginWithToken
}
//hack block 1***********
});//startup function
var connection = DDP.connect("http://localhost:3060");
Accounts.connection= connection;
//COMMENT: Ideally this should not be needed if the core takes care of this use case of a different connection for Accounts
//hack block 2***********
Accounts.users = new Meteor.Collection('users', {
connection: connection
});
//hack block 2***********
Tracker.autorun(function () {
//No code which directly affects the functionality. Just for testing
console.log(Meteor.user());
Accounts.connection.call('user',function(err,result){
if(err)
console.log(err);
if(result){
console.log(result);
if(result._id === Meteor.user()._id){
console.log("Server and client shows that the same user has logged in");
} else {console.log("Server and client shows different users");}
}
})
});
Template.register.events({
'submit #register-form' : function(e, t) {
e.preventDefault();
var email = t.find('#account-email').value
, password = t.find('#account-password').value;
Accounts.createUser({email:email,password:password}, function(err,result){
if (err) {
// Inform the user that account creation failed
console.log(err);
} else {
// Success. Account has been created and the user
// has logged in successfully.
console.log("registered user");
console.log('response is '+ result);
console.log(Meteor.user());
}
});//createUser
return false;
}
});//register
Template.login.events({
'submit #login-form': function(e,t){
e.preventDefault();
var email = t.find('#login-email').value
, password = t.find('#login-password').value;
Meteor.loginWithPassword(email, password, function(err){
if (err)
console.log(err);
else
// The user has been logged in.
console.log('logged in successfully');
});
return false;
}
});//login
Template.statusloggedin.events({
'click #logout': function(e,t){
e.preventDefault();
Meteor.logout();
return false;
}
});//logout
}

Categories

Resources