I am building an android app which pays someone. I explored Stripe Connect and it has an API and flow for website which requires displaying a stripe connect button and also needs a re-direct uri.
However, I can not find anything on for Android which allows to show a connect button and prompt user to create or connect a stripe account natively on Android device. Should I use a webview to do this or is there some more elegant way to do this?
As far as I know, there're no native SDK for mobile stripe connect. I did the webview route for android. Was trivial, but I agree that I wished there're a more elegant solution to this.
For those who are wondering on how to do this (since I can't find any doc out there), here you go:
Create a button that will open a new intent with a web view.
The webview should load the oauth/authorize endpoint ("https://connect.stripe.com/oauth/authorize?response_type=code&client_id=[YOUR_API_KEY]&scope=read_write"). Do not forget to enable javascript on your webview.
Once the form in webview is filled, Stripe will redirect to the redirect_url you provided with the authorization code if the authorization is successful. Have your web service parse that authorization code.
Have your service make a post to stripe oauth/token with providing grant_type, client_id, code, and client_secret.
Stripe will then respond back with the token (auth credentials) that you needed. Store that for later use & you're pretty much done.
I know this is quite an old one but, After investing my 2 days and trying, searching a lot of techniques to create stripe account in android platform I found Stripe API which solves my problem...
Firstly, here is the jar file you have to include in your project.
Then you have to initialize key provided you at the dashboard
Stripe.apiKey = "sk_test_xxxxxxxxxxxxxxxxxxxxxxxx";
RequestOptions requestOptions = RequestOptions.builder()
.setApiKey("sk_test_xxxxxxxxxxxxxxxxxxxxxxxx").build();
Map<String, Object> accountParams = new HashMap<String, Object>();
accountParams.put("managed", false);
accountParams.put("country", "US");
accountParams.put("email", "some#email.com");
To create an account use create() method for Account class with there parameter create link
try {
Account create = Account.create(accountParams, null);
} catch (AuthenticationException e) {
e.printStackTrace();
}
Then to retrieve account detail pass account id to retrieve() method
try {
Account detail = Account.retrieve("acct_xxxxxxxxxxxxxx", null);
} catch (AuthenticationException e) {
e.printStackTrace();
}
You can find more at Stripe Android API, and yes please do correct me if I am wrong..
Exception you need to catch AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException
Related
As the title says, I'm trying to use the Google Sign-In API with a Spring Boot backend server, as described here.
Just to describe the context, the Spring backend is basically a resource+authentication server, that is currently providing Oauth2 authentication to a second spring boot application containing the frontend website, via Google SSO or simple form login (similar to what's described here).
My original idea was to mimic the #EnableOauth2Sso annotation by simply providing an access token to the android app and attach it to every request as "Bearer ".
Using the user credentials for this was pretty straightforward: I simply make a request to the server at "/oauth/token", using those credentials inserted by the user as authentication and I correctly receive the access token.
Now, I have absolutely no idea on how to build a similar procedure with the Google API in Android. The tutorial page I linked before describes how to get a token ID and how the server should validate it, but after that I don't know what to do.
So far I've managed to add a filter to the security chain that simply checks the token like this:
private Authentication attemptOpenIDAuthentication(#NonNull String tokenString){
String clientId = authServices.getClientId();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, factory)
.setAudience(Arrays.asList(clientId, androidClient))
.build();
try {
GoogleIdToken token = verifier.verify(tokenString);
if (token != null) {
return authServices.loadAuthentication(token.getPayload());
} else {
throw new InvalidTokenException("ID token is null");
}
} catch (GeneralSecurityException | IOException e) {
throw new BadCredentialsException("Could not validate ID token");
}
}
This manages indeed to create an Authentication object, but how can I generate an access token after the authentication filtering?
To recap, so far I've got:
The Android app successfully retrieves the Google token ID and sends it to the server
The server sucessfully intercepts the request and validates the token
I'm basically missing the third point where I return a proper access token to the Android client.
Here you are a simple scheme to better understand the situation:
Is there any other way to validate the token and get an access token from the server, or should I completely change the authentication procedure on Android?
As far as I can tell: Yes, you need an access token from the server. If I understand this correctly, a webapp is already authenticated via Oauth on your backend, so the procedure is similar here: Load the user with the google-ID and generate a token. In my application I used a JWT which is valid for 30 days. If the token expires, the Google authentication in the app is usually still valid, so the token can be renewed using the Google ID. With Oauth you can also send a refresh-token directly.
It is important that the app always checks the Google authentication first and only in a second step that of the backend.
For the Authentication process on the backend u may need to manually implement a dedicated securityConfiguration for this. Have a look at the jhipster project, they implemented a custom jwt-authentication which may give you an idea how it works.
I've been following this link https://spring.io/guides/tutorials/spring-boot-oauth2 for implementing security to my own resource server. My final goal was to have custom login oauth server to access resource server from an android app which I've achieved using grant_type=password.
Now I would like to add social logins like Facebook to the same flow. I was able to make it work for web apps easily,I even got the accessToken from facebook in native android app but now what? After so much searching I was not able to find anything good for an android app. So my questions are:
How to add social login using spring oauth2 to an android app. Any links?
Should I be using Spring social with spring security for my goal. If yes, how?
I've been using JDBCTokenStore to persist my tokens in case my server restarts. If I get my token to server somehow how should I store it?
Please let me know if my understanding is incorrect.
Without digging too deep into the details, you can take the token you get from the client and use it to create a new connection via the connection repository. Of course, you'll also need to know which use the connection belongs to. In the end, the code will look something like this:
Code:
UsersConnectionRepository ucr = ...; // probably injected
ConnectionRepository cr = ucr.createConnectionRepository(userId); // you determine the userId somehow
ConnectionData cd = new ConnectionData(...); // lots of params...you'll fill those in.
FacebookConnectionFactory fcf = ...; // create or inject this
Connection<Facebook> conn = fcf.createConnection(cd);
cr.addConnection(conn);
As you can see, the code above is rough...I'm leaving a lot for you to fill in. But that's roughly how you'd do it.
I try to use Google oauth to authenticate users on my android app.
Then I would like to send it to my app server so it can connect at any time with Google calendar.
I tried to use
GoogleAuthUtil.getToken(getApplicationContext(), mAccountName, mScope);
Following this article:
https://developers.google.com/accounts/docs/CrossClientAuth
When I use it with scope
mScope = "oauth2:https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile";
I get a token, which is valid for an hour
But when I try to get an authorization code (so I can get a refresh token that is valid for longer time, using
mScope2 ="oauth2:server:client_id:{CLIENT_ID}.apps.googleusercontent.com"+ ":api_scope:https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile";
I receive either "invalid_scope" or "Unknown" exceptions.
What am I doing wrong?
EDIT:
OK, After creating a new app on google API console and adding plus.login to the scope I get a code, but for some reason my server can't resolve this token. When tying to resolve server gets an error about the redirection URL.
BTW, When I do the web flow with same parameters it works.
OK, found the solution, I expected Google to have a lot better documentation about working with Google Oauth and Android. A few things you have to know to work with Android and offline token
When you create google Client ID Don't create a service application before you create a web application
Must include https://www.googleapis.com/auth/plus.login in your scope
The weirdest, to resolve the one time authorization code on my server, I had to use the redirection URL from the Android client ID details (which doesn't even look like a url) and not from the Web client details on Google API console.
That scope string is only documented to work when passed to GoogleAuthUtil(), see http://developer.android.com/reference/com/google/android/gms/auth/GoogleAuthUtil.html, on Android. But it would be cool if it worked on iOS too; our infrastructure there is a little behind where we’re at on Android.
I have had the same issue then i realised that my app is not published and is in debug mode, so i had to add test users to the Google project -> Consent Screen, then i was able to fetch the token for the added test user.
You just need to follow the correct steps/format for specifying the scopes. Find them here https://developers.google.com/android/guides/http-auth#SpecifyingScopes
I want to post a simple status message to a Twitter account that's linked to my app. All users of my app will post to the same Twitter account.
I've registered my app with Twitter (according to the guidance given here: How to post a tweet from an Android app to one specific account?) and I have the necessary ConsumerKey, ConsumerSecret, AccessToken and AccessTokenSecret. I've set the account to Read & Write, and set the REQUEST type to GET.
I'm using Twitter4J and installed the twitter4j-core-3.0.3.jar into my app. The Manifest file has the required "android.permission.INTERNET". This is the code …::
AccessToken a = new AccessToken(AccessToken, AccessTokenSecret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(ConsumerKey, ConsumerSecret);
twitter.setOAuthAccessToken(a);
try
{
twitter.updateStatus("Tweet Test #1");
Log.v(TAG, "Twitter Tweet sent!");
}
catch (TwitterException e)
{
// TODO Auto-generated catch block
Log.e(TAG, "Error sending Tweet:" + e.getMessage());
}
The twitter.updateStatus("xxxxxx") call causes an exception that reports “Received authentication challenge is null” in the logcat.
I assumed I could just post, but it seems Twitter wants something more?
Can anybody offer any advice as to what I'm doing wrong?
Managed to get to the bottom of this in the end!
My particular problem was that I didn't enter a Callback URL in the Twitter Apps setup page. I'm only interested in sending tweets to my app's linked Twitter account and I already have the 4 tokens/secrets, so I don't need to get the user to authorise thier own account via my app. As such, I don't need a Callback URL.
Unfortunately, the Twitter apps page lets you leave that field blank when you request the tokens/secret, and they don't make it clear that the Callback URL is a required field. If you don't need it, you can put absolutely anything you like in there; But if you leave it blank, Twitter won't let you tweet from your app! Setting the access type to "Read & Write" is good enough just to update status, but set it to "Read, Write & Direct Messages" if you want to do more.
Some tutorials say you should set the app type to "Browser" (instead of "Desktop"), but that option seems to have disappeared from the Twitter apps page, so I guess that's no longer important.
I managed to find some very good tutorials about tweeting from an Android app (here, here and, in particular, here) which make it clear that the Callback URL is a requirement, and go on to explain very clearly how to get it to work.
Have you checked to make sure there aren't any extra whitespaces in your Twitter4J configuration file? Double-check each of your consumer.. and access.. fields just in case.
I have an android app that the user logs in to via facebook. I am trying to access my symfony api without logging in another time. Is it possible to log in to symfony with just the access token that I get from the android app?
Yes, it is possible. You'll need to implement a custom authentication provider and possibly a custom user provider to authenticate a user with token (and possibly retrieve him by token).
Ok so just a wrapup of what I managed to do.
I tried to modify fosFacebookBundle to accept access_tokens but in the end of the day I had to just do everything from scratch following the links I got from Zalas. I got the user from the accesstoken via the FacebookProvider class in fosFacebookBundle.
I had to inject Facebook, and FacebookProvider into my FacebookTokenListener. I am not even shure that this is secure. Somebody might be able to login with a access token from another site(I havn't tested it yet). The accesstoken is also in plaintext in the header. All in all not a very nice solution.
$this->facebook->setAccessToken($request->headers->get("access_token"));
$fbUid = $this->facebook->getUser();
if(!$fbUid){
throw new AccessDeniedHttpException("invalid access token");
}
$user = $this->facebookProvider->findUserByFbId($fbUid);
$token = new FacebookTokenToken($user);
Thanks for the links!