[JAVA] J'ai essayé d'automatiser tout, y compris l'authentification en deux étapes de Google OAuth

J'aime personnellement l'implémentation autour de l'authentification, mais je n'ai pas implémenté Google OAuth, j'ai donc profité de l'occasion pour l'implémenter.

La fonction OAuth est fournie par divers fournisseurs tels que FaceBook, Yahoo et Twitter, mais pour Google, les paramètres sont générés dynamiquement par JavaScript à chaque fois, de sorte que la partie authentification utilise chromedriver / Selenium (bibliothèque de scraping) et le navigateur. Nous avons décidé de mettre en œuvre l'authentification automatique de base.

De plus, lorsque la connexion automatique est gênante, Google nécessite une authentification en deux étapes en plus du nom d'utilisateur et du mot de passe, ce qui vaut donc la peine d'être automatisé. .. Lorsque vous essayez de vous connecter automatiquement, Google enverra un code d'authentification pour l'authentification en deux étapes à l'adresse e-mail de réinitialisation, mais cette fois, j'ai ignoré cet e-mail à un serveur de messagerie de réception uniquement utilisant AWS SES et que Après avoir stocké le courrier dans S3, le code de vérification écrit dans le corps du courrier est automatiquement lu et la valeur est automatiquement saisie.

Les paramètres SES sont maintenant renouvelés, mais juste au cas où, l'URL de référence est répertoriée ci-dessous. https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/receiving-email-setting-up.html

La séquence est la suivante, mais j'ai essayé d'automatiser tout le flux suivant (démarrage du navigateur> demande d'authentification> authentification> émission de jetons d'accès).

スクリーンショット 2019-10-18 3.43.28.png

environnement:  Java: 1.8  Selenium: 3.12.0  ChromeDriver: 77.0.3865.40  Chrome: 77.0.3865.90

Puisque Maven a été utilisé comme outil de construction cette fois, le contenu de pom.xml est le suivant.

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>googleOAuth</groupId>
  <artifactId>googleOAuth</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>googleOAuth</name>
  <dependencies>
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.12.0</version>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
    <version>1.11.651</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.7</version>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-sts</artifactId>
    <version>1.9.6</version>
</dependency>
</dependencies>
  <build>
  	<plugins>
  		<plugin>
  			<groupId>org.apache.maven.plugins</groupId>
  			<artifactId>maven-shade-plugin</artifactId>
  			<version>3.2.1</version>
  		</plugin>
  		      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
            <archive>
              <manifest>
                <mainClass>googleOAuth.GoogleOAuth2</mainClass>
              </manifest>
            </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
  	</plugins>
  </build>
</project>

GoogleOAuth.java


package google;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.util.IOUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class GoogleOAuth {

	private final String clientId;
	private final String clientSecret;
	private final String redirectUri;
	private final String scope;
	private final String responseType;
	private final String tokenUrl;
	private final String driverpath;
	private String emailAddress;
	private String password;
	private String recEmailAddress;
	private String lastName;
	private String firstName;
	private String BucketName;
	private String LocalPath;

	public GoogleOAuth() {
		clientId = "*****"; //identité du client
		clientSecret = "*****"; //Secret du client
		redirectUri = "*****"; //Rediriger l'URI
		scope = "https://www.googleapis.com/auth/userinfo.profile";
		responseType = "code";
		tokenUrl = "https://accounts.google.com/o/oauth2/token";
		BucketName = "*****"; //Nom du compartiment S3
		LocalPath = "*****"; //Chemin de stockage du courrier
		driverpath = "*****"; //chemin de chromedriver
		emailAddress = "*****"; //adresse e-mail de connexion
		password = "*****"; //mot de passe
		recEmailAddress = "*****"; //Adresse du serveur de courrier entrant SES
		lastName = "*****"; //LastName
		firstName = "*****"; //FirstName
	}

	public static void main(String[] args) throws IOException {
		GoogleOAuth google = new GoogleOAuth();
		String aZcode = google.getAzCode();
		JsonNode access_token = google.getAccessToken(aZcode);
		System.out.println(access_token);

	}

	public String getAzCode() throws IOException {
		final String PATH = this.driverpath;
		System.setProperty("webdriver.chrome.driver", PATH);
        WebDriver driver = new ChromeDriver();
        final String URL = "https://accounts.google.com/o/oauth2/auth?client_id=" + this.clientId + "&redirect_uri=" +
        		this.redirectUri + "&scope=" + this.scope + "&response_type=" + this.responseType;

        driver.get(URL);


        try {
        	driver.findElement(By.xpath("//*[@id=\"identifierId\"]")).sendKeys(this.emailAddress);;
	        driver.findElement(By.xpath("//*[@id=\"yDmH0d\"]")).click();
	        Thread.sleep(5000);

	        driver.findElement(By.xpath("//*[@id=\"recoveryIdentifierId\"]")).sendKeys(this.recEmailAddress);;
	        driver.findElement(By.xpath("//*[@id=\"queryPhoneNext\"]/span/span")).click();
	        Thread.sleep(5000);

	        driver.findElement(By.xpath("//*[@id=\"lastName\"]")).sendKeys(this.lastName);;
	        driver.findElement(By.xpath("//*[@id=\"firstName\"]")).sendKeys(this.firstName);;
	        driver.findElement(By.xpath("//*[@id=\"collectNameNext\"]/span/span")).click();
	        Thread.sleep(5000);

        	driver.findElement(By.xpath("//*[@id=\"idvpreregisteredemailNext\"]/span/span")).click();
        	Thread.sleep(5000);

        	this.downloadFile();
        	Thread.sleep(3000);
        	String token = this.getToken();

	        driver.findElement(By.xpath("//*[@id=\"idvPinId\"]")).sendKeys(token);;
	        driver.findElement(By.xpath("//*[@id=\"idvpreregisteredemailNext\"]/span")).click();
	        Thread.sleep(3000);

	        driver.findElement(By.xpath("//*[@id=\"view_container\"]/div/div/div[2]/div/div/div/form/span/section/div/div/div/div/ul/li[3]/div/div/div[2]")).click();
	        Thread.sleep(3000);

	        driver.findElement(By.xpath("//*[@id=\"identifierId\"]")).sendKeys(this.emailAddress);;
	        driver.findElement(By.xpath("//*[@id=\"identifierNext\"]/span/span")).click();
	        Thread.sleep(3000);

	        driver.findElement(By.xpath("//*[@id=\"password\"]/div[1]/div/div[1]/input")).sendKeys(this.password);;
	        driver.findElement(By.xpath("//*[@id=\"passwordNext\"]/span/span")).click();
	        Thread.sleep(3000);
	        } catch (InterruptedException e) {
	        	System.out.println("Caught InterruptedException: " + e);
	        }

        	String currentUrl = driver.getCurrentUrl();
        	//System.out.println(currentUrl);
    		int biginIdx = currentUrl.indexOf("code=");
    		int endIdx = currentUrl.indexOf("&scope");
    		String aZcode = currentUrl.substring(biginIdx+5, endIdx);

    		driver.quit();

    		return aZcode;
		}


	public JsonNode getAccessToken(String code) throws IOException {
		URL url = new URL(this.tokenUrl);
		StringBuffer result = new StringBuffer();
		HttpURLConnection  conn = null;
		conn = (HttpURLConnection) url.openConnection();
		conn.setDoOutput(true);
		conn.setRequestMethod("POST");
		conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		conn.setUseCaches(false);
		String params = new String("code=" + code + "&client_id=" + this.clientId + "&client_secret=" + this.clientSecret +
				"&redirect_uri=" + this.redirectUri + "&grant_type=authorization_code");
        OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
        out.write(params);
        out.close();
        conn.connect();

        final int status = conn.getResponseCode();
        if (status == 200) {
            final InputStream input = conn.getInputStream();
            String encoding = conn.getContentEncoding();
            if(null == encoding){
                encoding = "UTF-8";
            }
            final InputStreamReader inReader = new InputStreamReader(input, encoding);
            final BufferedReader bufReader = new BufferedReader(inReader);
            String line = null;
            while((line = bufReader.readLine()) != null) {
                result.append(line);
            }
            bufReader.close();
            inReader.close();
            input.close();
        } else {
            System.out.println(status);
        }

        conn.disconnect();

        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(result.toString());

        return root;
	}

	public void downloadFile() throws IOException {
		AmazonS3 s3 = AmazonS3ClientBuilder.standard()
                .withRegion("us-east-1")
                .build();

		ObjectListing objectListing = s3.listObjects(new ListObjectsRequest()
		        .withBucketName(this.BucketName));

		for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
		    System.out.println(objectSummary.getKey());
		    String objectKey = objectSummary.getKey();
		    S3Object object = s3.getObject(new GetObjectRequest(this.BucketName, objectKey));
		    try {
				FileOutputStream fos = new FileOutputStream(new File(this.LocalPath));
				IOUtils.copy(object.getObjectContent(), fos);
				fos.close();
				s3.deleteObject(new DeleteObjectRequest(this.BucketName, objectKey));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	public String getToken() throws IOException {
		File file = new File(this.LocalPath);
		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);
		String json_str;
		String data = "";
		int cnt = 0;

		while ((json_str = br.readLine()) != null) {
			cnt += 1;
			if ((cnt>= 73)&&(128 >= cnt)){
			data += json_str;
			}
		}

        Charset charset = StandardCharsets.UTF_8;
        byte[] bytes = Base64.getDecoder().decode(data.getBytes());
        String decode_str = new String(bytes, charset);
		int biginIdx = decode_str.indexOf("<strong style=\"text-align: center; font-size: 24px; font-weight: bold;\">");
		int endIdx = decode_str.indexOf("</strong>");
		String token = decode_str.substring(biginIdx+72, endIdx);

		br.close();
		return token;
	}
}

Après avoir exécuté le code ci-dessus et terminé l'authentification / l'autorisation, vous pouvez enfin obtenir le jeton d'accès comme suit.

{"access_token":"ya29.ImCiBwhJcCZ-JIW9ZlGDe2ysCBkNzRpG9mgr_-ocM_A32Dh1bzJbHAHOT_iKi6GNAVovWDLgyKclHJaP1uqTODQ61LJomWAUzhWSnMsd4ddGKTeIUfOeSQocVbUzikxcWjU","expires_in":3596,"scope":"https://www.googleapis.com/auth/userinfo.profile","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IjNkYjNlZDZiOTU3NGVlM2ZjZDlmMTQ5ZTU5ZmYwZWVmNGY5MzIxNTMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNjUwMDQxMDk4ODAzLTBtMG81Y2IxZ2ZraW43cDJwN2ZuaWNhYnUxaWdvdnVnLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNjUwMDQxMDk4ODAzLTBtMG81Y2IxZ2ZraW43cDJwN2ZuaWNhYnUxaWdvdnVnLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE1OTcwNTg3NjcwMjI4MTk2Njc4IiwiYXRfaGFzaCI6IjhGZmJSa3BYQ1VoWUduX0VTN2tENnciLCJpYXQiOjE1NzEzMzE4ODYsImV4cCI6MTU3MTMzNTQ4Nn0.oXK4EhivivgJqhO6cjJ7ZyeTBPW9IrTOvM_GGeDcNJ6XXTOVtRd8nv3pRT1SHDSTTgkco6tAI8ZN-dWDD-LVhqkhGTjM-USzR2UbXhMsd4z6WRYGMPfzuLCkGRGZwp0Gqd7ctITlIWJr0N8xLPEGNSHx_IPZtabOaP4ME9YN0-XQg-x2tE32LdRI4ttvW7D1lSeYPKdzWf_12i9zoLnblc2MiGTupww91PlQSaLGoprFPVutI_57c1IraBsCmMGuW0Nke4vps7YoFhaaxDhB4XuJCpyIvpADHuOydq3RPY5WCV8YIzFXsFCa1f-Z7QyJNuZgcFf7WLWcjXQZkD4i8g"}

Recommended Posts

J'ai essayé d'automatiser tout, y compris l'authentification en deux étapes de Google OAuth
J'ai essayé d'automatiser la fabrication des sushis avec python
J'ai essayé d'automatiser l'arrosage du pot avec Raspberry Pi
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de commencer avec Hy
J'ai essayé d'implémenter CVAE avec PyTorch
J'ai essayé de résoudre TSP avec QAOA
J'ai essayé de prédire l'année prochaine avec l'IA
J'ai essayé d'implémenter la lecture de Dataset avec PyTorch
J'ai essayé d'utiliser lightGBM, xg boost avec Boruta
J'ai essayé d'apprendre le fonctionnement logique avec TF Learn
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé de détecter rapidement un mouvement avec OpenCV
J'ai essayé d'intégrer Keras dans TFv1.1
J'ai essayé d'obtenir des données CloudWatch avec Python
J'ai essayé de sortir LLVM IR avec Python
J'ai essayé de détecter un objet avec M2Det!
J'ai essayé de prédire la survie du Titanic avec PyCaret
J'ai essayé "Receipt OCR" avec l'API Google Vision
J'ai essayé d'utiliser Linux avec Discord Bot
J'ai essayé d'étudier DP avec séquence de Fibonacci
J'ai essayé de démarrer Jupyter avec toutes les lumières d'Amazon
J'ai essayé de juger Tundele avec Naive Bays
J'ai essayé d'entraîner la fonction péché avec chainer
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de déplacer Faster R-CNN rapidement avec pytorch
J'ai essayé d'implémenter et d'apprendre DCGAN avec PyTorch
J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé de démarrer avec le script python de blender_Part 01
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
J'ai essayé de lire et d'enregistrer automatiquement avec VOICEROID2
J'ai essayé de démarrer avec le script python de blender_Partie 02
J'ai essayé de générer ObjectId (clé primaire) avec pymongo
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de créer un pipeline ML avec Cloud Composer
J'ai essayé de déboguer.
J'ai essayé de découvrir notre obscurité avec l'API Chatwork
[Introduction à Pytorch] J'ai essayé de catégoriser Cifar10 avec VGG16 ♬
J'ai essayé de résoudre le problème avec Python Vol.1
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
J'ai essayé de créer une application OCR avec PySimpleGUI
J'ai essayé d'implémenter SSD avec PyTorch maintenant (Dataset)
J'ai essayé d'interpoler le masque R-CNN avec un flux optique
J'ai essayé de passer par l'optimisation bayésienne. (Avec des exemples)
J'ai essayé d'accéder aux feuilles de calcul Google en utilisant Python
J'ai essayé de trouver la classe alternative avec tensorflow
[Introduction à AWS] J'ai essayé de jouer avec la conversion voix-texte ♪
J'ai essayé de résoudre la théorie des nombres entiers d'AOJ avec Python