2017年4月29日 星期六

Instagram access token 的取得

今天要介紹的是如何取得Instagram的Access Token,及
用Access Token來取得使用者的資訊,如發佈的貼文(Instagram的貼文都是圖片或影片)圖片url等。

今天的需求是:

  1. 想要取得自己在Instagram上面的貼文圖片。
  2. 想要將取得的貼文圖片展示在網頁上。

使用技術:

  1. JSP
  2. Jquery

先講Instagram 官方步驟

  1. 一開始如果沒有Instagram帳號,請註冊一個。
  2. 進入Instagram的developer console,填好相關資訊註冊成為Developer。
  3. 自己建立一個網頁,假設網址為REDIRECT-URI
  4. Manage Clients建立一個App,其中"Valid redirect URIs"填上步驟3的REDIRECT-URI
  5. 進入
    https://api.instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECT-URI&response_type=code
    其中 CLIENT-ID 為已建立之App的 CLIENT-ID , REDIRECT-URI 即為自己建立網頁的網址。
  6. 待使用者登入並授權以後,會被引導至 REDIRECT-URI 頁面,並會以GET方式在Url後面帶上一個 code 參數。
  7. 這個 code 只能用一次,
    以以下參數
    client_id : App的client_id
    client_secret : App的client_secret
    grant_type : "authorization_code"
    redirect_uri : App的redirect_uri
    code : 剛剛得到的code
    請求 https://api.instagram.com/oauth/access_token,
    成功的話會在Response中得到access_token的參數,即我們要PO文資訊時需要的access_token。
  8. 要到access_token以後,就可以用來要各種使用者的資料了,在Developer console的左邊"Endpoints"中有提供各種Endpoints,這邊我們使用下面這個就好:
    https://api.instagram.com/v1/users/self/media/recent/?access_token=ACCESS_TOKEN
    請在ACCESS_TOKEN填上剛要到的,代表使用者的ACCESS_TOKEN,成功的話會回傳使用者最近的照片PO文資料。

下面以實測的程式碼來演示,



檔案結構為:


重要檔案簡介:
  1. instagramTest.jsp :
    測試主頁面。
  2. getCode.jsp :
    用來得到Code。
    所需帶入參數:
    code
  3. getAccessToken.jsp :
    用來得到AccessToken。
    所需帶入參數:
    code
    client_id
    client_secret
    redirect_uri
  4. getPostListByAccessToken.jsp :
    用來得到PO文資訊。
    所需帶入參數:
    accessToken
  5. js/instagramTest.js :
    instagramTest.jsp頁面的邏輯。
先看Demo畫面
  1. 一開始的畫面,從Developer console將client_id、redirect_uri(此例例如是XXXX)、client_secret
  2. 點擊"Get Instagram Code"後會打開一個視窗,一開始可能會要求登入及授權,授權過後畫面上會顯示Code,並且也會在原來的視窗寫上Code的值。
  3. 接著按下"Get Instagram Access Token",成功的話,會在Access Token處上填上其值。

  4. 再按下"Get Pictures"按鈕後,如果成功的話,下面就會顯示自已在Instagram的圖片了。
重要檔案源碼:
  1. instagramTest.html:
    測試主頁面。
    所需代入參數:
    code
    原始碼:
    <!DOCTYPE html>
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>Instagram Test</title>
    
            <script src="js/jquery-3.2.1.min.js"></script>
            <script src="js/instagramTest.js"></script>
        </head>
        <body>
            <b>Step1:</b>
            <div>client_id : <input type="text" id="client_id_input" /></div>
            <div>redirect_uri : <input type="text" id="redirect_uri_input" /></div>
            <div>Code : <i id="Code_view"></i></div>
            <div><button id="getCode_btn">Get Instagram Code</button></div>
    
            <br/>
    
            <b>Step2:</b>
            <div>client_secret : <input type="text" id="client_secret_input" /></div>
            <div>Access Token : <i id="accessToken_view"></i></div>
            <div><button id="getAccessToken_btn">Get Instagram Access Token</button></div>
    
            <br/>
    
            <b>Step3:</b>
            <div>Get Post Pictures, please enter Access Token</div>
            <div>Access Token : <input type="text" id="accessToken_input" /></div>
            <button id="getPictures_btn">Get Pictures</button>
            <div id="postImageZone"></div>
    
        </body>
    </html>
  2. getCode.jsp :
    用來得到Code。
    所需帶入參數:
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@page import="com.oreilly.servlet.ParameterParser"%>
    <%
            try{
                    ParameterParser parser = new ParameterParser(request);
                    parser.setCharacterEncoding("UTF-8");
      //得到Instagram在Url後面以Get方式代入的參數, code
                    String code = parser.getStringParameter("code", "");
                    request.setAttribute("code", code);
            }catch(Exception e){
                    request.setAttribute("exception", e.getMessage());
            }
    %>
    <!DOCTYPE html>
    <html>
        <head>
            <script>
                window.opener.document.getElementById("Code_view").innerHTML = "${code}";
            </script>
        </head>
        <body>
            <div>Instagram Code: ${code}</div>
            <div>Exception:</div>
            ${exception}
        </body>
    </html>
  3. getAccessToken.jsp :
    用來得到AccessToken。
    所需帶入參數:
    code
    client_id
    client_secret
    redirect_uri
    原始碼:
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    
    <%@page import="org.apache.http.util.EntityUtils"%>
    <%@page import="org.apache.http.impl.client.DefaultHttpClient"%>
    <%@page import="org.apache.http.HttpResponse"%>
    <%@page import="org.apache.http.client.entity.UrlEncodedFormEntity"%>
    <%@page import="org.apache.http.message.BasicNameValuePair"%>
    <%@page import="java.util.ArrayList"%>
    <%@page import="org.apache.http.client.methods.HttpPost"%>
    <%@page import="org.json.JSONObject"%>
    <%@page import="com.oreilly.servlet.ParameterParser"%>
    <%
            try{
                    JSONObject resultJSON = new JSONObject();
      
                    ParameterParser parser = new ParameterParser(request);
                    parser.setCharacterEncoding("UTF-8");
      
                    String code = parser.getStringParameter("code", "");
                    String client_id = parser.getStringParameter("client_id", "");
                    String client_secret = parser.getStringParameter("client_secret", "");
                    String redirect_uri = parser.getStringParameter("redirect_uri", "");
      
                    String accessToken = getaccessToken(code, client_id, client_secret, redirect_uri);
                    resultJSON.put("accessToken", accessToken);
      
                    out.print(resultJSON.toString());
            }catch(Exception e){
                    out.print("{\"error\" : \"" + e.getMessage() + "\"}");
            }
    %>
    <%!
            String getaccessToken(String code, String client_id, String client_secret, String redirect_uri) throws Exception{
                    String accessToken = "";
      //以Post方式向instagram取得AccessToekn
                    HttpPost httpRequest = new HttpPost("https://api.instagram.com/oauth/access_token");
      //需要附上的參數
                    ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>( );
                    params.add(new BasicNameValuePair("client_id", client_id));
                    params.add(new BasicNameValuePair("client_secret", client_secret));
                    params.add(new BasicNameValuePair("grant_type", "authorization_code"));
                    params.add(new BasicNameValuePair("redirect_uri", redirect_uri));
                    params.add(new BasicNameValuePair("code", code));
      
      
                    httpRequest.setEntity(new UrlEncodedFormEntity ( params , "UTF-8" ));
                    HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
                    String responseInfo = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); System.out.println(responseInfo);
                    JSONObject responseJSON = new JSONObject(responseInfo);
                    //取得Access Token
                    accessToken = responseJSON.getString("access_token");
      
                    return accessToken;
            }
    %>
  4. getPostListByAccessToken.jsp :
    用來得到PO文資訊。
    所需帶入參數:
    accessToken
    原始碼:
    <%@page import="org.apache.http.util.EntityUtils"%>
    <%@page import="org.apache.http.impl.client.DefaultHttpClient"%>
    <%@page import="org.apache.http.HttpResponse"%>
    <%@page import="org.apache.http.client.methods.HttpGet"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    
    <%@page import="org.json.JSONObject"%>
    <%@page import="org.json.JSONArray"%>
    <%@page import="com.oreilly.servlet.ParameterParser"%>
    <%
        try {
            ParameterParser parser = new ParameterParser(request);
            parser.setCharacterEncoding("UTF-8");
    
            String accessToken = parser.getStringParameter("accessToken", "accessToken");
            JSONArray postList = getPostList(accessToken);
    
            out.print(postList.toString());
    
        } catch (Exception e) {
            out.print("{\"error\" : \"" + e.getMessage() + "\"}");
        }
    %>
    <%!
        JSONArray getPostList(String accessToken) throws Exception {
            JSONArray postList = new JSONArray();
            //使用Get向instagram取得Po文資料
            HttpGet httpRequest = new HttpGet("https://api.instagram.com/v1/users/self/media/recent/?access_token=" + accessToken);
    
            HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
            String responseInfo = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
            JSONObject responseJSON = new JSONObject(responseInfo);
    
            postList = (JSONArray) responseJSON.get("data");
    
            return postList;
        }
    %>
  5. js/instagramTest.js :
    instagramTest.jsp頁面的邏輯。
    $(document).ready(function () {
        $("#getCode_btn").click(function () {
    
            var redirect_uri = $("#redirect_uri_input").val();
            var client_id = $("#client_id_input").val();
            //打開新視窗,向instagram請求code, 其會導向redirect_uri參數設定的頁面,並以Get方式代入code
            window.open("https://api.instagram.com/oauth/authorize/?response_type=code&client_id=" + client_id + "&redirect_uri=" + redirect_uri, "", config = 'height=500,width=500');
        });
        //////////////////////////////////////////////////
        $("#getAccessToken_btn").click(function () {
            var code = $("#Code_view")[0].innerHTML;
            var client_id = $("#client_id_input").val();
            var client_secret = $("#client_secret_input").val();
            var redirect_uri = $("#redirect_uri_input").val();
            //取得Access Token
            $.ajax({
                method: "POST",
                url: "ajax/getAccessToken.jsp",
                data: {
                    code: code,
                    client_id: client_id,
                    client_secret: client_secret,
                    redirect_uri: redirect_uri
                },
                dataType: "json"
            }).done(function (data) {
                if (!data.error) {
                    $("#accessToken_view")[0].innerHTML = data.accessToken;
                    $("#accessToken_input").val(data.accessToken)
                } else {
                    alert(data.error);
                }
            }).fail(function (error) {
                alert("Error");
            });
        });
        //////////////////////////////////////////////
        $("#getPictures_btn").click(function () {
            var accessToken = $("#accessToken_input").val();
            //取得Po文資訊
            $.ajax({
                method: "POST",
                url: "ajax/getPostListByAccessToken.jsp",
                data: {
                    accessToken: accessToken
                },
                dataType: "json"
            }).done(function (data) {
                var i;
                if (!data.error) {
                    for (i = 0; i < data.length; i++) {
                        var postImage = $("<img/>")
                        postImage.attr("src", data[i].images.low_resolution.url);
                        $("#postImageZone").append(postImage);
                    }
                } else {
                    alert(data.error);
                }
            }).fail(function (error) {
                alert("Error");
            });
        });
    });

源始碼下載:

沒有留言 :

張貼留言