How can I validate the Access Token and how to get the information of token using Access Token?
Is this the url to validate the Access Token?
https://mydomain/oauth2/v1/tokeninfo?access_token=tYPJr7F6ArYkd1Vdlh1gbhWlnz8NLA9TZmky2NpvaHZxhw14udbmFNRG1pKMKVEY&token_type=bearer
Here is an example of the data taken from token (the example is from Azure auth - but it does not matter both use OAuth2).
That's how you extract the information from the Token:
in getAuthInteractiveCallback() or getAuthSilentCallback() methods:
private AuthenticationCallback getAuthSilentCallback() {
return new AuthenticationCallback() {
#Override
public void onSuccess(AuthenticationResult authenticationResult) {
/* Successfully got a token, call api now */
Log.d(TAG, "Successfully authenticated");
Log.d(TAG, "ID Token: " + authenticationResult.getIdToken());
Log.d(TAG, "ID Token: " + authenticationResult.getAccessToken());
try {
String token = authenticationResult.getIdToken();
String token2 = token.substring(token.indexOf('.') + 1, token.lastIndexOf('.'));
byte[] data = Base64.decode(token2, Base64.DEFAULT);
String text = new String(data, StandardCharsets.UTF_8);
JSONObject jsonObject = new JSONObject(text);
JSONArray jsonArray = new JSONArray(jsonObject.getString("emails"));
String eMail = jsonArray.get(0).toString();
Log.d(TAG, "eMail: " + eMail);
} catch (JSONException ex) { }
authResult = authenticationResult;
state.setAuthResult(authResult);
}
#Override
public void onError(MsalException exception) {
}
#Override
public void onCancel() {
}
};
}
In addition you can get iod, expiration time (exp), auth time (auth_time), versiov (ver)
Related
I'm currently creating a test application to test using the latest facebook SDK to update our existing application problem is that I need to get the user birthday. I'm confused on this since the the SDK3 and above provides more information than the updated SDK4 and I'm lost on how to get the birthday as all the answers I've seen so far doesn't provide the birthday on my end. Here's my code so far:
LoginButton CallBacks:
fbLogin = (LoginButton) findViewById(R.id.login_button);
fbLogin.setReadPermissions(Arrays.asList("email", "user_birthday"));
fbLogin.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult loginResult) {
// App code
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
if (object.has("id"))
id = object.getString("id");
if (object.has("name"))
userName = object.getString("name");
if (object.has("email"))
userEmail = object.getString("email");
if (object.has("gender"))
gender = object.getString("gender");
if (object.has("birthday"))
birthday = object.getString("birthday");
String profile_URL = "https://graph.facebook.com/" + id+ "/picture?type=large";
LogCat.show(id + "\n" + userName + "\n" + userEmail + "\n" + birthday + "\n" + profile_URL + "\n" + gender);
} catch (Exception e) {
e.printStackTrace();
LogCat.show("Error:" + e.getMessage());
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id, name, email,gender, birthday");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
// App code
Toast.makeText(SplashLogin.this, "CANCEL", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(FacebookException exception) {
// App code
Toast.makeText(SplashLogin.this, "" + exception.toString(), Toast.LENGTH_SHORT).show();
}
});
The JSON response returns only the ID and name, email and gender of my account but doesn't include the birthday. Did I missed out something?
According to the latest sdk of facebook, to get birthday you need to first submit your application for review. On test applications you can just get the public profile which includes the following things
id
cover
name
first_name
last_name
age_range
link
gender
locale
picture
timezone
updated_time
verified
For more information you can read the following documentation from this link
If your app requests this permission Facebook will have to review how
your app uses it. link
Facebook don't give user birthday by default.You have to use extended permissions.
I solve this problem by enable permission of Birthday in my app from the Facebook Developer Console.
fbSignUp.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(final LoginResult loginResult) {
// App code
GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
try {
Data.fbAccessToken = loginResult.getAccessToken().getToken();
LogCat.show(loginResult.getAccessToken().getToken());
if (object.has("id")) {
id = object.getString("id");
Data.fbId = object.getString("id");
}
if (object.has("name")) {
userName = object.getString("name");
;
Data.fbUserName = object.getString("name");
}
if (object.has("email")) {
userEmail = object.getString("email");
Data.fbUserEmail = object.getString("email");
}
if (object.has("birthday")) {
userBirthDay = object.getString("birthday");
}
else {
if (userEmail == null || "".equalsIgnoreCase(userEmail)) {
if (userName != null && !"".equalsIgnoreCase(userName)) {
userEmail = userName + "#facebook.com";
Data.fbUserEmail = Data.fbUserName + "#facebook.com";
} else {
userEmail = id + "#facebook.com";
Data.fbUserEmail = Data.fbId + "#facebook.com";
}
}
}
} catch (Exception e) {
e.printStackTrace();
LogCat.show("Error:" + e.getMessage());
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id, name, email,birthday,gender");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel() {
// App code
Toast.makeText(RegisterScreen.this, "CANCEL", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(FacebookException exception) {
// App code
Toast.makeText(RegisterScreen.this, "" + exception.toString(), Toast.LENGTH_SHORT).show();
}
});
i am using twitter integration using fabric, now issue is i am able to get all the details of user except email address. following is my code, can any one help me with that
public void login(Result<TwitterSession> result) {
//Creating a twitter session with result's data
TwitterSession session = result.data;
//Getting the username from session
final String username = session.getUserName();
//This code will fetch the profile image URL
//Getting the account service of the user logged in
Call<User> userResult = Twitter.getApiClient(session).getAccountService().verifyCredentials(true, false);
userResult.enqueue(new Callback<User>() {
#Override
public void failure(TwitterException e) {
}
#Override
public void success(Result<User> userResult) {
User user = userResult.data;
String twitterImage = user.profileImageUrl;
try {
Log.d("imageurl", user.profileImageUrl);
Log.d("name", user.name);
System.out.println("Twitter Email"+user.email);
//Log.d("email", user.email);
Log.d("des", user.description);
Log.d("followers ", String.valueOf(user.followersCount));
Log.d("createdAt", user.createdAt);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
This is how I fetched the user email of an user:
final TwitterSession twitterSession = result.data;
twitterAuthClient.requestEmail(twitterSession, new com.twitter.sdk.android.core.Callback<String>() {
#Override
public void success(Result<String> emailResult) {
String email = emailResult.data;
// ...
}
#Override
public void failure(TwitterException e) {
callback.onTwitterSignInFailed(e);
}
});
So you have to call TwitterAuthClient.requestEmail() once you got a successful Result<TwitterSession> upon authorization.
Be aware that you'll have to contact Twitter support to enable access to users' email for your app. An error message with this will show up.
Here is my code to get details from twitter:
private void intializeTwitterUI() {
loginButton = (TwitterLoginButton)
findViewById(R.id.twitter_login_button);
loginButton.setCallback(new Callback<TwitterSession>() {
#Override
public void success(Result<TwitterSession> result) {
// The TwitterSession is also available through:
// TWITTER.getInstance().core.getSessionManager().getActiveSession()
TwitterSession session = result.data;
// TODO: Remove toast and use the TwitterSession's userID
// with your app's user model
String msg = "Twitter: #" + session.getUserName() + " logged in! (#" + session.getUserId() + ")";
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
/**
*
*/
AccountService _AccountService = Twitter.getApiClient(result.data).getAccountService();
_AccountService.verifyCredentials(true, true).enqueue(new retrofit2.Callback<User>() {
#Override
public void onResponse(Call<User> call, retrofit2.Response<User> response) {
Log.d(TAG, "Twitter user is: " + response.toString());
Log.d(TAG, "Twitter-Email" + response.body().email);
Log.d(TAG, "Twitter-profileImage" + response.body().profileImageUrl);
Log.d(TAG, "Twitter-ID" + response.body().id);
twitterDetails = response.body().email + "," + response.body().profileImageUrl + "," + response.body().id;
}
#Override
public void onFailure(Call<User> call, Throwable t) {
Log.e(TAG, "verifyCredentials failed! " + t.getLocalizedMessage());
}
});
}
For those that want to do it with Kotlin can try in this way:
val session = TwitterCore.getInstance().sessionManager.activeSession as TwitterSession
val authClient = TwitterAuthClient()
authClient.requestEmail(session, object : Callback<String>(){
override fun failure(exception: TwitterException?) {
email.setText("Welcome to Twitter")
}
override fun success(result: Result<String>?) {
email.setText("Welcome " + result?.data)
}
})
It is possible to request an email address from users, but it requires your app to be whitelisted.
check here Is there a way to get an user's email ID after verifying his/her Twitter identity using OAuth?
I've been trying to implement an app which saves user accounts (id, password and token) with the Android AccountManager. Been using this as my reference for implementing the functionality.
I am able to show my AuthenticationActivity and create accounts (which show up correctly in the Settings > Accounts after I create them). After I add a new account I try to immediately login the user with the token received which I save with setAuthToken(). However this never works and I see that the authToken is always null. I then have to run the app for a second time and login again after which it works.
The code where I add a new account (from my signup activity) is,
private void addNewAccount(final AccountManager am, final String accountType, String authTokenType) {
Log.d(TAG, "addNewAccount(): " + accountType + ", " + authTokenType);
am.addAccount(accountType, authTokenType, null, null, this, new AccountManagerCallback<Bundle>() {
#Override
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
final String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
Log.d(TAG, "addNewAccount() -> bundle = " + bundle + ", authToken = " + authToken);
if (!TextUtils.isEmpty(authToken)) {
startLoggedInActivity(authToken);
} else {
Log.d(TAG, "token is null"); // <- always get here
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, null);
}
And the code where I finish the login (after I receive the token and add the new user) is,
private void finishLogin(Intent intent) {
Log.d(TAG, "finishLogin(): " + intent.getExtras());
if (intent.hasExtra(KEY_ERROR_MESSAGE)) {
Toast.makeText(getBaseContext(), intent.getStringExtra(KEY_ERROR_MESSAGE), Toast.LENGTH_SHORT).show();
setResult(RESULT_CANCELED, intent);
} else {
String accountName = intent.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
String accountPassword = intent.getStringExtra(PARAM_USER_PASS);
final Account account = new Account(accountName, intent.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE));
if (getIntent().getBooleanExtra(ARG_IS_ADDING_NEW_ACCOUNT, false)) {
String authtoken = intent.getStringExtra(AccountManager.KEY_AUTHTOKEN);
// Creating the account on the device and setting the auth token we got
// (Not setting the auth token will cause another call to the server to authenticate the user)
mAccountManager.addAccountExplicitly(account, accountPassword, null);
Log.d(TAG, "finishLogin() -> addAccountExplicitly: " + account + ", " + accountPassword);
mAccountManager.setAuthToken(account, mAuthTokenType, authtoken);
Log.d(TAG, "finishLogin() -> setAuthToken: " + authtoken);
} else {
mAccountManager.setPassword(account, accountPassword);
Log.d(TAG, "finishLogin() -> setPassword: " + account + ", " + accountPassword);
}
setAccountAuthenticatorResult(intent.getExtras());
setResult(RESULT_OK, intent);
}
finish();
}
Does anyone know what the problem could be (been struggling with this for quite some time now :( )?
I am trying to write a code in Android to create a basic Quickblox session using my credential. But whenever i kill the app and open the app again then the Quickblox sdk ask for signin. I am getting "Token is Required" error response.
MyCode :
public class MainActivity extends AppCompatActivity {
String tokenError = "No Token";
String phoneNumber = "phonenumber";
String token;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
if (!QBChatService.isInitialized()) {
QBChatService.init(this);
}
try {
String token = QBAuth.getSession().getToken();
if(token!=null) {
// Session Valid //
} else {
createSession();
}
} catch (QBResponseException e) {
e.printStackTrace();
//alertbox("Session Exception " + e.toString());
createSession();
}
}
private void createSession() {
final QBUser user = new QBUser();
String inputUser = phoneNumber;
user.setFullName(inputUser);
user.setLogin(inputUser);
user.setPassword(inputUser);
QBAuth.createSession(user, new QBEntityCallback<QBSession>() {
#Override
public void onSuccess(QBSession qbSession, Bundle bunde) {
try {
QBAuth.getBaseService().setToken(qbSession.getToken());
QBAuth.getBaseService().setTokenExpirationDate(new Date(1443033000000L));
tokenError = QBAuth.getBaseService().getToken();
Toast.makeText(getApplicationContext(), " " + QBAuth.getBaseService().getToken() + " :: ", Toast.LENGTH_SHORT).show();
} catch (BaseServiceException e) {
e.printStackTrace();
tokenError = "Error " + e.toString();
}
String msg = tokenError;
alertbox(msg);
if (tokenError.contains("Error")) {
signIn(phoneNumber);
}
}
#Override
public void onSuccess() {
}
#Override
public void onError(List<String> list) {
}
});
}
This is my above code , i am login to QuickBlox if token is null but after login i am getting the token.
But if i kill the app then the token is gone and need to login again.
It's kind of costly process from app side , so please let me know some solution , suggest me how to keep the token alive (at-least for 2hrs).
My application allows the user to connect with Facebook. I want to get userprofile information after login with Facebook (using Facebook SDK 4.0.1). I think that I should use aynctask to get it but I don't know how.
loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>()
{
#Override
public void onSuccess(LoginResult loginResult)
{
System.out.println("onSuccess");
msginfo.setText("You can now share image on facebook");
otherview.setVisibility(View.VISIBLE);
GraphRequest request = GraphRequest.newMeRequest
(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback()
{
#Override
public void onCompleted(JSONObject object, GraphResponse response)
{
// Application code
Log.v("LoginActivity", response.toString());
//System.out.println("Check: " + response.toString());
try
{
String id = object.getString("id");
idT.setText(object.getString("id"));
ppv.setProfileId(object.getString("id"));
nameT.setText(object.getString("name"));
emailT.setText(object.getString("email"));
locationT.setText(object.getString("address"));
String name = object.getString("name");
String email = object.getString("email");
String gender = object.getString("gender");
String birthday = object.getString("birthday");
// String location = object.getString("location");
// String location = object.getString("user_location");
// String location = object.getString("address");
System.out.println(id + ", " + name + ", " + email + ", " + gender + ", " + birthday);
// locationT.setText(location);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender, birthday,link");
request.setParameters(parameters);
request.executeAsync();
}
#Override
public void onCancel()
{
System.out.println("onCancel");
}
#Override
public void onError(FacebookException exception)
{
System.out.println("onError");
Log.v("LoginActivity", exception.getCause().toString());
}
});
And I can get the profile informations in the current activity but not in the next one.
I think you are missing permissions
parameters.putString("fields", "id,name,email,gender,picture,birthday");
And then you can easily get profile pic
object.getJSONObject("picture").getJSONObject("data").getString("url");
Hope it helps.