Oauth 2.0 Autorisierung für LinkedIn in Android

Auch wenn es keine solche Android-Sdk von linkedIn (wie facebook und twitter sdk für Android) .Setting up linkedIn Autorisierung mit Oauth 1.0 war noch einfach mit:

  • Scribe-java
  • Social-auth für Android.
  • Und die Liste der Werkzeuge hier.

Aber es ist nicht die gleiche Geschichte für die Autorisierung mit Oauth2.0. Nicht zu viele nützliche Bibliotheken oder Android-Beispiele. Ich habe versucht, diese zu benutzen:

  • IOException, die von AccountManagerFuture.getResults geworfen wird, während die Verbindung lebendig ist
  • Android - wie bekomme ich google plus access token?
  • Verwenden Sie das Aktualisierungs-Token, wenn auth-Token im Konto-Authentifizierer abgelaufen ist
  • Zugriff auf Google plus Client aus mehreren Aktivitäten
  • Wo ist der beste Ort, um globals (auth token) in Android zu speichern
  • Android: Wie bekomme ich Refresh Token von Google Sign-In API?
    • Android Oauth-Client
    • Tnj

    Ich habe gelesen, dass Oauth 2.0 ist viel einfacher zu implementieren als die 1.0. Trotzdem kann ich das nicht tun.

    Irgendwelche Hinweise zur Implementierung von Oauth2.0 für LinkedIn in Android?

  • Speichern von UI auf Orientierungsänderung - onSaveInstanceState funktioniert nicht wie erwartet, wenn das Fragment beibehalten wird
  • Symbolleistenuntertitel erscheinen nicht
  • Wie stellst du Min- und Max-Daten in einem Android DatePicker?
  • Extrahieren / unterscheiden ActivityAlias ​​Name von TargetActivity
  • Wie man Bluetooth basierte Anwendung auf Androidx86 oben auf VirtualBox mit eingebautem Laptop bluetooth testet
  • Android: Viewpager und FragmentStatePageAdapter
  • 4 Solutions collect form web for “Oauth 2.0 Autorisierung für LinkedIn in Android”

    Oauth2.0-Authentifizierung für LinkedIN.

    Schritt 1:

    • Registrieren Sie Ihre App mit linkedIn, indem Sie diesem Dokument folgen . Und bekomme deine api_key und api_secret.

    Schritt 2:

    Hauptaktivität:

    public class MainActivity extends Activity { /*CONSTANT FOR THE AUTHORIZATION PROCESS*/ /****FILL THIS WITH YOUR INFORMATION*********/ //This is the public api key of our application private static final String API_KEY = "YOUR_API_KEY"; //This is the private api key of our application private static final String SECRET_KEY = "YOUR_API_SECRET"; //This is any string we want to use. This will be used for avoiding CSRF attacks. You can generate one here: http://strongpasswordgenerator.com/ private static final String STATE = "E3ZYKC1T6H2yP4z"; //This is the url that LinkedIn Auth process will redirect to. We can put whatever we want that starts with http:// or https:// . //We use a made up url that we will intercept when redirecting. Avoid Uppercases. private static final String REDIRECT_URI = "http://com.amalbit.redirecturl"; /*********************************************/ //These are constants used for build the urls private static final String AUTHORIZATION_URL = "https://www.linkedin.com/uas/oauth2/authorization"; private static final String ACCESS_TOKEN_URL = "https://www.linkedin.com/uas/oauth2/accessToken"; private static final String SECRET_KEY_PARAM = "client_secret"; private static final String RESPONSE_TYPE_PARAM = "response_type"; private static final String GRANT_TYPE_PARAM = "grant_type"; private static final String GRANT_TYPE = "authorization_code"; private static final String RESPONSE_TYPE_VALUE ="code"; private static final String CLIENT_ID_PARAM = "client_id"; private static final String STATE_PARAM = "state"; private static final String REDIRECT_URI_PARAM = "redirect_uri"; /*---------------------------------------*/ private static final String QUESTION_MARK = "?"; private static final String AMPERSAND = "&"; private static final String EQUALS = "="; private WebView webView; private ProgressDialog pd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //get the webView from the layout webView = (WebView) findViewById(R.id.main_activity_web_view); //Request focus for the webview webView.requestFocus(View.FOCUS_DOWN); //Show a progress dialog to the user pd = ProgressDialog.show(this, "", this.getString(R.string.loading),true); //Set a custom web view client webView.setWebViewClient(new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { //This method will be executed each time a page finished loading. //The only we do is dismiss the progressDialog, in case we are showing any. if(pd!=null && pd.isShowing()){ pd.dismiss(); } } @Override public boolean shouldOverrideUrlLoading(WebView view, String authorizationUrl) { //This method will be called when the Auth proccess redirect to our RedirectUri. //We will check the url looking for our RedirectUri. if(authorizationUrl.startsWith(REDIRECT_URI)){ Log.i("Authorize", ""); Uri uri = Uri.parse(authorizationUrl); //We take from the url the authorizationToken and the state token. We have to check that the state token returned by the Service is the same we sent. //If not, that means the request may be a result of CSRF and must be rejected. String stateToken = uri.getQueryParameter(STATE_PARAM); if(stateToken==null || !stateToken.equals(STATE)){ Log.e("Authorize", "State token doesn't match"); return true; } //If the user doesn't allow authorization to our application, the authorizationToken Will be null. String authorizationToken = uri.getQueryParameter(RESPONSE_TYPE_VALUE); if(authorizationToken==null){ Log.i("Authorize", "The user doesn't allow authorization."); return true; } Log.i("Authorize", "Auth token received: "+authorizationToken); //Generate URL for requesting Access Token String accessTokenUrl = getAccessTokenUrl(authorizationToken); //We make the request in a AsyncTask new PostRequestAsyncTask().execute(accessTokenUrl); }else{ //Default behaviour Log.i("Authorize","Redirecting to: "+authorizationUrl); webView.loadUrl(authorizationUrl); } return true; } }); //Get the authorization Url String authUrl = getAuthorizationUrl(); Log.i("Authorize","Loading Auth Url: "+authUrl); //Load the authorization URL into the webView webView.loadUrl(authUrl); } /** * Method that generates the url for get the access token from the Service * @return Url */ private static String getAccessTokenUrl(String authorizationToken){ return ACCESS_TOKEN_URL +QUESTION_MARK +GRANT_TYPE_PARAM+EQUALS+GRANT_TYPE +AMPERSAND +RESPONSE_TYPE_VALUE+EQUALS+authorizationToken +AMPERSAND +CLIENT_ID_PARAM+EQUALS+API_KEY +AMPERSAND +REDIRECT_URI_PARAM+EQUALS+REDIRECT_URI +AMPERSAND +SECRET_KEY_PARAM+EQUALS+SECRET_KEY; } /** * Method that generates the url for get the authorization token from the Service * @return Url */ private static String getAuthorizationUrl(){ return AUTHORIZATION_URL +QUESTION_MARK+RESPONSE_TYPE_PARAM+EQUALS+RESPONSE_TYPE_VALUE +AMPERSAND+CLIENT_ID_PARAM+EQUALS+API_KEY +AMPERSAND+STATE_PARAM+EQUALS+STATE +AMPERSAND+REDIRECT_URI_PARAM+EQUALS+REDIRECT_URI; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } private class PostRequestAsyncTask extends AsyncTask<String, Void, Boolean>{ @Override protected void onPreExecute(){ pd = ProgressDialog.show(MainActivity.this, "", MainActivity.this.getString(R.string.loading),true); } @Override protected Boolean doInBackground(String... urls) { if(urls.length>0){ String url = urls[0]; HttpClient httpClient = new DefaultHttpClient(); HttpPost httpost = new HttpPost(url); try{ HttpResponse response = httpClient.execute(httpost); if(response!=null){ //If status is OK 200 if(response.getStatusLine().getStatusCode()==200){ String result = EntityUtils.toString(response.getEntity()); //Convert the string result to a JSON Object JSONObject resultJson = new JSONObject(result); //Extract data from JSON Response int expiresIn = resultJson.has("expires_in") ? resultJson.getInt("expires_in") : 0; String accessToken = resultJson.has("access_token") ? resultJson.getString("access_token") : null; Log.e("Tokenm", ""+accessToken); if(expiresIn>0 && accessToken!=null){ Log.i("Authorize", "This is the access Token: "+accessToken+". It will expires in "+expiresIn+" secs"); //Calculate date of expiration Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.SECOND, expiresIn); long expireDate = calendar.getTimeInMillis(); ////Store both expires in and access token in shared preferences SharedPreferences preferences = MainActivity.this.getSharedPreferences("user_info", 0); SharedPreferences.Editor editor = preferences.edit(); editor.putLong("expires", expireDate); editor.putString("accessToken", accessToken); editor.commit(); return true; } } } }catch(IOException e){ Log.e("Authorize","Error Http response "+e.getLocalizedMessage()); } catch (ParseException e) { Log.e("Authorize","Error Parsing Http response "+e.getLocalizedMessage()); } catch (JSONException e) { Log.e("Authorize","Error Parsing Http response "+e.getLocalizedMessage()); } } return false; } @Override protected void onPostExecute(Boolean status){ if(pd!=null && pd.isShowing()){ pd.dismiss(); } if(status){ //If everything went Ok, change to another activity. Intent startProfileActivity = new Intent(MainActivity.this, ProfileActivity.class); MainActivity.this.startActivity(startProfileActivity); } } }; } 

    Und das xmlLayout:

      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <WebView android:id="@+id/main_activity_web_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> 

    Das Token wird in der sharedpreference-Datei gespeichert.

    Einfaches androides projekt repo hier in github .

    OAuth 2.0 ist viel einfacher als 1.0 und kann ohne Hilfe von einer externen Bibliothek durchgeführt werden. Allerdings, wenn Sie bereits mit scribe-Java, wird es noch einfacher.

    Die Umsetzung ist einfach. Sie müssen ein WebView erstellen, das über einen benutzerdefinierten WebViewClient der das Ladeverhalten für Ihre Callback-URL erfasst und überschreibt. Wenn also die WebView versucht, diese URL zu laden, können Sie den Prozess abfangen und einen Verifizierer extrahieren. Der Prüfer kann an scribe-java weitergegeben werden, um für einen Zugriffstoken auszutauschen.

    Um den gesamten Prozess zu starten, musst du einfach deinem WebView , um die Autorisierungs-URL zu laden.

    Ich habe Beispielcode hier gehostet. Die App authentifiziert mit der Puffer-API, aber der Großteil des Codes kann wiederverwendet werden. Sie interessieren sich vielleicht für das Fragment, das meine benutzerdefinierte WebView und den Hintergrundjob beherbergt, der Zugriffstoken erhält.

    Fühlen Sie sich frei zu fragen mich irgendwelche Follow-up Fragen.

    Ich habe es funktioniert, aber es hat mich gebraucht … irgendwann.

    Ich folgte der LinkedIn Authentication , um das zu verwalten.
    Ich empfehle immer noch, diesen Link noch zu lesen, da ich nicht alle Fälle in meinen Beispielen abdecke (Fehler, Fehlerbehandlung, beste Pratices, Parameterverwendung, präzise Dokumentation …)

    • Zuerst musst du deinen LinkedIn API Key und Secret Key haben. Wenn Sie dies nicht tun, registrieren Sie sich hier.

    • Zweitens benötigen Sie eine Aktivität in der Anwendung, die den Autorisierungscode erhalten kann. Dafür muss es in der Datei "AndroidManifest.xml" als browsable (startable from a browser) gesetzt werden:

        <activity android:name=".ResultActivity" android:label="" > <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> </intent-filter> 

      Obwohl nicht empfohlen, ist es möglich, ein Daten-Tag verwenden, um URIs mit einem benutzerdefinierten Schema abzurufen:

        <data android:scheme="oauth"/> 
    • Danach müssen Sie den Benutzer in den Berechtigungsdialog des LinkedInes umleiten, indem er eine bestimmte URL verwendet:

       https://www.linkedin.com/uas/oauth2/authorization?response_type=code &client_id=YOUR_API_KEY &scope=SCOPE &state=STATE &redirect_uri=YOUR_REDIRECT_URI 

      Sie können ein WebView verwenden, um es direkt in Ihrer Anwendung anzuzeigen, oder lassen Sie das System es durch eine Absicht behandeln wie:

       Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(/* FULL URL */)); startActivity(intent); 

      Das einzige Problem hier ist, dass die API nicht akzeptiert Schemata anders als http oder https, was bedeutet, dass Sie nicht einfach die Absicht URI als den Parameter redirect_uri übergeben können.

      So habe ich eine Landing-Seite auf meinem Server erstellt, mit nur Zweck ist es, auf die Anwendung umzuleiten. Wir können uns etwas vorstellen (in hässlich verkürzen PHP) (Intent ref.) :

       header('Location: ' . "intent:#Intent;component=your.package/.ResultActivity;S.code=" . $_GET['code'] . ";S.state=" . $_GET['state'] . ";end"); die(); 

      Also ist alles eingestellt! Jetzt das onCreate(Bundle) der ResultActivity:

       Intent intent = getIntent(); String authorizationCode = intent.getStringExtra("code"); 

      Es gibt einen anderen Weg, um Parameter hier zu übergeben, wenn das Daten-Tag früher verwendet wurde.

    • Fast dort! Jetzt müssen Sie nur eine einfache POST-Anfrage auf dieser URL durchführen:

       https://www.linkedin.com/uas/oauth2/accessToken?grant_type=authorization_code &code=AUTHORIZATION_CODE &redirect_uri=YOUR_REDIRECT_URI &client_id=YOUR_API_KEY &client_secret=YOUR_SECRET_KEY 

      Rückgabe eines JSON- Objekts auf Erfolg:

      {"expires_in":5184000,"access_token":"AQXdSP_W41_UPs5ioT_t8HESyODB4FqbkJ8LrV_5mff4gPODzOYR"}

    Et voilà! Sie können jetzt Ihre API-Anrufe mit dem access_token machen. Vergessen Sie nicht, es irgendwo zu speichern, also haben Sie nicht durch diese Schritte wieder.

    Ich hoffe das war nicht zu lange zu lesen und dass es einigen Leuten helfen kann. 🙂

      @Override public boolean shouldOverrideUrlLoading(WebView view, String authorizationUrl) { //This method will be called when the Auth proccess redirect to our RedirectUri. //We will check the url looking for our RedirectUri. if(authorizationUrl.startsWith(REDIRECT_URI)){ Log.i("Authorize", ""); Uri uri = Uri.parse(authorizationUrl); //We take from the url the authorizationToken and the state token. We have to check that the state token returned by the Service is the same we sent. //If not, that means the request may be a result of CSRF and must be rejected. String stateToken = uri.getQueryParameter(STATE_PARAM); if(stateToken==null || !stateToken.equals(STATE)){ Log.e("Authorize", "State token doesn't match"); return true; } //If the user doesn't allow authorization to our application, the authorizationToken Will be null. String authorizationToken = uri.getQueryParameter(RESPONSE_TYPE_VALUE); if(authorizationToken==null){ Log.i("Authorize", "The user doesn't allow authorization."); return true; } Log.i("Authorize", "Auth token received: "+authorizationToken); //Generate URL for requesting Access Token String accessTokenUrl = getAccessTokenUrl(authorizationToken); //We make the request in a AsyncTask new PostRequestAsyncTask().execute(accessTokenUrl); }else{ //Default behaviour Log.i("Authorize","Redirecting to: "+authorizationUrl); webView.loadUrl(authorizationUrl); } return true; } 

    Und in deinem AsyncTask:

    Private Klasse PostRequestAsyncTask erweitert AsyncTask {

      @Override protected void onPreExecute(){ pd = ProgressDialog.show(MainActivity.this, "", MainActivity.this.getString(R.string.loading),true); } @Override protected Boolean doInBackground(String... urls) { if(urls.length>0){ String url = urls[0]; HttpClient httpClient = new DefaultHttpClient(); HttpPost httpost = new HttpPost(url); try{ HttpResponse response = httpClient.execute(httpost); if(response!=null){ //If status is OK 200 if(response.getStatusLine().getStatusCode()==200){ String result = EntityUtils.toString(response.getEntity()); //Convert the string result to a JSON Object JSONObject resultJson = new JSONObject(result); //Extract data from JSON Response int expiresIn = resultJson.has("expires_in") ? resultJson.getInt("expires_in") : 0; String accessToken = resultJson.has("access_token") ? resultJson.getString("access_token") : null; Log.e("Tokenm", ""+accessToken); if(expiresIn>0 && accessToken!=null){ Log.i("Authorize", "This is the access Token: "+accessToken+". It will expires in "+expiresIn+" secs"); //Calculate date of expiration Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.SECOND, expiresIn); long expireDate = calendar.getTimeInMillis(); ////Store both expires in and access token in shared preferences SharedPreferences preferences = MainActivity.this.getSharedPreferences("user_info", 0); SharedPreferences.Editor editor = preferences.edit(); editor.putLong("expires", expireDate); editor.putString("accessToken", accessToken); editor.commit(); return true; } } } }catch(IOException e){ Log.e("Authorize","Error Http response "+e.getLocalizedMessage()); } catch (ParseException e) { Log.e("Authorize","Error Parsing Http response "+e.getLocalizedMessage()); } catch (JSONException e) { Log.e("Authorize","Error Parsing Http response "+e.getLocalizedMessage()); } } return false; } @Override protected void onPostExecute(Boolean status){ if(pd!=null && pd.isShowing()){ pd.dismiss(); } if(status){ //If everything went Ok, change to another activity. Intent startProfileActivity = new Intent(MainActivity.this, ProfileActivity.class); MainActivity.this.startActivity(startProfileActivity); } } }; 
    Das Android ist ein Google Android Fan-Website, Alles über Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.