7

मैं टॉमकैट पर चल रहे स्प्रिंग-एमवीसी एप्लिकेशन पर काम कर रहा हूं जिसमें मैं Google ड्राइव कार्यक्षमता का उपयोग करना चाहता हूं। मैंने अपनी स्थानीय मशीन पर एक सेवा खाते के साथ प्रयास किया और मुझे कोई समस्या नहीं थी। लेकिन जब मैंने सर्वर पर कोड अपलोड किया, तो ब्राउज़र यूआरएल खोला नहीं जाएगा। तब मैंने सोचा, मुझे सेवा खाते का उपयोग नहीं करना चाहिए, मुझे सामान्य वेब-एप्लिकेशन खाते का उपयोग करना चाहिए। अब जब मैं ऐसा करता हूं, तो मुझे एक redirect_uri_mismatch मिलता है।वसंत: Google प्रमाणीकरण redirect_uri_mismatch और URL ब्राउज़र पर खुला नहीं होगा

मुझे एक बात समझ में नहीं आ रही है, मैं जेएसओएन में रीडायरेक्ट यूआरएल प्रवाह में सेट कर रहा हूं, क्यों पृथ्वी पर इसे यादृच्छिक पोर्ट नंबरों के साथ redirect_url मिल रहा है। यदि मैं ब्राउज़र यूआरएल में पोर्ट नंबर बदलता हूं, तो यह ठीक काम करता है। लेकिन फिर भी सर्वर पर यह ब्राउज़र यूआरएल नहीं खोलता है, मैं इसे टॉमकैट लॉग में देख सकता हूं, लेकिन लापरवाह चीज़ यूआरएल नहीं खोलती है।

http://localhost/authorizeuser 
http://localhost:8080/ 
http://localhost:8080 
http://localhost 
http://localhost:8080/Callback 
https://testserver.net/Callback 
http://testserver.net/Callback 
http://127.0.0.1 

यहाँ मेरी client_secret.json है:

यहाँ Google ऐप से मेरी रीडायरेक्ट URL हैं यहाँ

{"web": { 
    "client_id": "clientid", 
    "auth_uri": "https://accounts.google.com/o/oauth2/auth", 
    "token_uri": "https://accounts.google.com/o/oauth2/token", 
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 
    "client_email": "clientemailstuff", 
    "client_x509_cert_url": "certurlstuff", 
    "client_secret": "itsasecret", 
    "redirect_uris": ["http://localhost:8080/","http://localhost:8080"], 
    "javascript_origins": ["https://testserver.net", "http://testserver.net","http://localhost:8080"] 
}} 

और कोड है, जहां मैं प्रमाणित करने के लिए कोशिश कर रहा हूँ:

@Override 
    public Credential authorize() throws IOException { 
     InputStream in = 
       DriveQuickstartImpl.class.getResourceAsStream("/client_secret.json"); 
     GoogleClientSecrets clientSecrets = 
       GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in)); 

     GoogleAuthorizationCodeFlow flow = 
       new GoogleAuthorizationCodeFlow.Builder(
         HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES) 
         .setDataStoreFactory(DATA_STORE_FACTORY) 
         .setAccessType("offline") 
         .build(); 
     flow.newAuthorizationUrl().setState("xyz").setRedirectUri("http://localhost:8080/Callback"); 
     Credential credential = new AuthorizationCodeInstalledApp(
       flow, new LocalServerReceiver()).authorize("user"); 

     if(credential!=null && credential.getRefreshToken() != null){ 
      storeCredentials(credential); 
     } 
     return credential; 
    } 

यह मुझे मुख्य रूप से बंद कर रहा है क्योंकि मैं रीडायरेक्ट यूआरएल सेट कर रहा हूं, और इसे अभी अनदेखा किया जा रहा है और क्यों पृथ्वी पर एप्लिकेशन को तैनात किए जाने पर एक ब्राउज़र टैब खोला नहीं जाएगा।

अद्यतन स्प्रिंग समस्या भी तय, नीचे दिए गए कोड बिल्ला या अन्य लोगों के साथ एक सर्वर पर GoogleDrive प्राधिकरण के लिए इस्तेमाल किया जा सकता है।

@Service 
@Transactional 
public class GoogleAuthorization{ 


    @Autowired 
    private DriveQuickstart driveQuickstart; 

    private static final String APPLICATION_NAME ="APPNAME"; 

    private static final java.io.File DATA_STORE_DIR = new java.io.File(
      "/home/deploy/store"); 

    private static FileDataStoreFactory DATA_STORE_FACTORY; 

    private static final JsonFactory JSON_FACTORY = 
      JacksonFactory.getDefaultInstance(); 

    private static HttpTransport HTTP_TRANSPORT; 

    private static final List<String> SCOPES = 
      Arrays.asList(DriveScopes.DRIVE); 

    private static final String clientid = "clientid"; 
    private static final String clientsecret = "clientsecret"; 

    private static final String CALLBACK_URI = "http://localhost:8080/getgooglelogin"; 

    private String stateToken; 

    private final GoogleAuthorizationCodeFlow flow; 

    public GoogleAuthorization(){ 
     try { 
      HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport(); 
      DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR); 

     } catch (GeneralSecurityException | IOException e) { 
      e.printStackTrace(); 
     } 

     flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, 
       JSON_FACTORY, clientid, clientsecret, SCOPES).setAccessType("offline").setApprovalPrompt("force").build(); 
     generateStateToken(); 

    } 



    /** 
    * Builds a login URL based on client ID, secret, callback URI, and scope 
    */ 
    public String buildLoginUrl() { 

     final GoogleAuthorizationCodeRequestUrl url = flow.newAuthorizationUrl(); 

     return url.setRedirectUri(CALLBACK_URI).setState(stateToken).build(); 
    } 

    /** 
    * Generates a secure state token 
    */ 
    private void generateStateToken(){ 
     SecureRandom sr1 = new SecureRandom(); 
     stateToken = "google;"+sr1.nextInt(); 
    } 

    /**s 
    * Accessor for state token 
    */ 
    public String getStateToken(){ 
     return stateToken; 
    } 

    /** 
    * Expects an Authentication Code, and makes an authenticated request for the user's profile information 
    * * @param authCode authentication code provided by google 
    */ 
    public void saveCredentials(final String authCode) throws IOException { 

     GoogleTokenResponse response = flow.newTokenRequest(authCode).setRedirectUri(CALLBACK_URI).execute(); 
     Credential credential = flow.createAndStoreCredential(response, null); 
     System.out.println(" Credential access token is "+credential.getAccessToken()); 
     System.out.println("Credential refresh token is "+credential.getRefreshToken()); 
// The line below gives me a NPE. 
     this.driveQuickstart.storeCredentials(credential); 
    } 
} 

नियंत्रक विधि:

@RequestMapping(value = "/getgooglelogin") 
    public String getGoogleLogin(HttpServletRequest request, HttpServletResponse response, HttpSession session,Model model) { 
// Below guy should be autowired if you want to use Spring. 
     GoogleAuthorization helper = new GoogleAuthorization(); 

     if (request.getParameter("code") == null 
       || request.getParameter("state") == null) { 

      model.addAttribute("URL", helper.buildLoginUrl()); 
      session.setAttribute("state", helper.getStateToken()); 

     } else if (request.getParameter("code") != null && request.getParameter("state") != null && request.getParameter("state").equals(session.getAttribute("state"))) { 
      session.removeAttribute("state"); 

      try { 
       helper.saveCredentials(request.getParameter("code")); 
       return "redirect:/dashboard"; 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return "newjsp"; 
    } 

newjsp सिर्फ यूआरएल पर क्लिक करने के लिए एक बटन है।

+0

रीडायरेक्ट uri सर्वर अनुरोध www.whatever.com/callback अपने उत्पादन सर्वर स्थानीय होस्ट नहीं है भेजने का स्थान है। – DaImTo

+0

@DaImTo: मैं इसके साथ सहमत हूं, लेकिन क्रेडेंशियल में मैंने जो रीडायरेक्ट यूरी का उल्लेख किया है उसे नहीं कहा जाता है। और अनुरोध करने के लिए मुझे रीडायरेक्ट यूआरएल सेट करने का कोई तरीका नहीं है, कोड इसे स्थानीयहोस्ट पर सेट कर रहा है: randomPortNumber eventhough मैंने स्थानीयहोस्ट का उपयोग करने के लिए JSON में निर्दिष्ट किया है: 8080। –

+0

क्लाइंट लाइब्रेरी आपके लिए उस स्थान से भेजी गई है जिसे आप भेज रहे हैं। आपको अपने कोड में रीडायरेक्ट यूआरआई सेट नहीं करना चाहिए। आपको उस रीडायरेक्ट यूरी को सेट करना चाहिए जिसे आप Google डेवलपर कंसोल से भेज रहे हैं और आपको बस इतना करना है। अपना विचार स्थापित करें ताकि यह यादृच्छिक पोर्ट नंबर – DaImTo

उत्तर

2

विशेष रूप से, आपको यादृच्छिक बंदरगाह मिल रहे हैं क्योंकि आप LocalServerReceiver का उपयोग कर रहे हैं, जो starts up a jetty instance on a free port को ऑथ कोड प्राप्त करने के लिए उपयोग कर रहे हैं।

उच्च स्तर पर, ऐसा लगता है कि आप web server application विकसित कर रहे हैं, लेकिन आप Google OAuth का उपयोग करने की कोशिश कर रहे हैं जैसे कि यह installed application था। यदि आप वास्तव में वेब सर्वर एप्लिकेशन बना रहे हैं, तो आपको अपने कॉलबैक यूआरएल में लोकहोस्ट के बजाय अपने सर्वर के होस्ट नाम का उपयोग करना चाहिए, जो अंतिम उपयोगकर्ता के लिए flow.newAuthorizationUrl() का उपयोग करके प्रमाणित करने के लिए एक लिंक प्रदान करना चाहिए, और अपना कॉलबैक flow.newTokenRequest(String) का उपयोग करके टोकन लाएं। यह भी सुनिश्चित करें कि आपके console में बनाए गए क्लाइंट आईडी प्रकार का वेब एप्लिकेशन है, या आप get redirect_uri_mismatch errors करेंगे। ऐसा करने का एक पूर्ण कार्य उदाहरण here पाया जा सकता है।

+0

मैं अब बदलाव करूँगा और आपको वापस ले जाऊंगा। बहुत बहुत धन्यवाद। –

+0

मेरा दोस्त, सब कुछ काम करने लगता है, बस कक्षा वसंत से कनेक्ट नहीं है। यही कारण है कि मुझे एनपीई मिल रहा है। मैं अपनी मुख्य पोस्ट संपादित कर रहा हूं, क्या आप कृपया जांच सकते हैं कि मैं क्या कर सकता हूं। –

+0

मैंने अभी अपनी पोस्ट संपादित की है। क्या आप आखिरी विधि में Google प्राधिकरण वर्ग की जांच कर सकते हैं, मुझे एनपीई मिल रही है क्योंकि वसंत ठीक से स्वचालन नहीं कर रहा है –

2
उपयोग करने के बजाय

:

Credential credential = new AuthorizationCodeInstalledApp(flow, 
        new LocalServerReceiver).authorize("user"); 

उपयोग

LocalServerReceiver localReceiver = new LocalServerReceiver. 
             Builder().setPort(XXXX).build(); 

एक स्थिर पोर्ट संख्या

Credential credential = new AuthorizationCodeInstalledApp(flow, 
             localReceiver).authorize("user"); 

की स्थापना यद्यपि आप अभ्यस्त पुनर्निर्देश url बदलने में सक्षम होने के लिए, फिर भी आप मेजबान के साथ ही बंदरगाह सेट कर सकते हैं। मेजबान उपयोग बदल रहा .setHost() विधि के लिए

तुम भी डिफ़ॉल्ट निर्माता के रूप में उपयोग कर सकते हैं:

Credential credential = new AuthorizationCodeInstalledApp(flow, 
      new LocalServerReceiver("Host", XXXX).authorize("user"); 
संबंधित मुद्दे