C'est un mot douloureux, OAuth 1.0 ... Je ne suis pas sûr car je n'ai pas tellement utilisé Spring, mais il semble que RestTemplate devrait être utilisé lors de l'utilisation de l'API. Mais avec OAuth 1.0, je n'y suis pas vraiment entré et j'ai fini par utiliser HttpClient. Existe-t-il une meilleure pratique pour accéder à l'API OAuth 1.0 au printemps? .. .. Veuillez enseigner s'il y a une meilleure façon.
(Ajouté le 06/08/2018) OAuth 1.0 semble bien fonctionner avec le projet frère de Spring Security appelé spring-security-oauth. https://projects.spring.io/spring-security-oauth/docs/oauth1.html Il y a beaucoup de gens qui ont essayé d'implémenter OAuth2 dans la rue, mais la 1.0 est vraiment rare.
Accédez à l'API OAuth 1.0 de Zaim pour obtenir les données.
Gradle La dépendance ressemble à ceci. Les éléments suivants sont obligatoires et les autres sont comme vous le souhaitez.
build.gradle
dependencies {
// spring-boot
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-devtools')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
// OAuth1.0a
compile('oauth.signpost:signpost-core:1.2.1.2')
compile('oauth.signpost:signpost-commonshttp4:1.2.1.2')
}
Ajoutez une nouvelle application ci-dessous. https://dev.zaim.net
Si vous l'ajoutez, vous pouvez obtenir les informations suivantes, alors prenez-en note.
Veillez à ne pas divulguer votre identifiant et votre secret de consommateur.
En savoir plus sur OAuth 1.0 ici. http://yuroyoro.hatenablog.com/entry/20100506/1273137673
Créez une instance en utilisant les informations que vous avez enregistrées lorsque vous avez ajouté une nouvelle application dans Zaim.
python
private static final String CONSUMER_KEY = "Informations d'enregistrement Zaim";
private static final String CONSUMER_SECRET = "Informations d'enregistrement Zaim";
private static final String REQUEST_TOKEN_URL = "Informations d'enregistrement Zaim";
private static final String AUTHORIZE_URL = "Informations d'enregistrement Zaim";
private static final String ACCESS_TOKEN_URL = "Informations d'enregistrement Zaim";
private OAuthConsumer consumer;
private OAuthProvider provider;
consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
provider = new CommonsHttpOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZE_URL);
C'est suffisant pour l'utilisation, mais bien sûr, vous devriez aller dans le fichier de propriétés, etc. pour les informations ici. Créez un bean pour la propriété.
application.properties
zaim.consumerKey=your_consumerKey
zaim.consumerSecret=your_consumerSecret
zaim.requestTokenUrl=https://api.zaim.net/v2/auth/request
zaim.authorizeUrl=https://auth.zaim.net/users/auth
zaim.accessTokenUrl=https://api.zaim.net/v2/auth/access
OAuthProperty
/**
*Obtenez et conservez les informations requises pour l'authentification OAuth à partir du fichier de propriétés
*/
public class OAuthProperty {
@Getter
@Value("${zaim.consumerKey}")
private String consumerKey;
@Getter
@Value("${zaim.consumerSecret}")
private String consumerSecret;
@Getter
@Value("${zaim.requestTokenUrl}")
private String requestTokenUrl;
@Getter
@Value("${zaim.authorizeUrl}")
private String authorizeUrl;
@Getter
@Value("${zaim.accessTokenUrl}")
private String accessTokenUrl;
}
BeanConfig.java
@Configuration
public class BeanConfig {
@Bean
OAuthProperty oAuthProperty() {
return new OAuthProperty();
}
//Puisque le accessToken est différent pour chaque utilisateur, il est nécessaire d'avoir au moins pour chaque session
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
OAuthConsumer oAuthConsumer(OAuthProperty oAuthProperty) {
return new CommonsHttpOAuthConsumer(oAuthProperty.getConsumerKey(),
oAuthProperty.getConsumerSecret());
}
//Puisque le accessToken est différent pour chaque utilisateur, il est nécessaire d'avoir au moins pour chaque session
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
OAuthProvider oAuthProvider(OAuthProperty oAuthProperty) {
return new CommonsHttpOAuthProvider(oAuthProperty.getRequestTokenUrl(),
oAuthProperty.getAccessTokenUrl(), oAuthProperty.getAuthorizeUrl());
}
}
Utilisez l'instance créée pour générer l'URL de la page d'authentification. Après vous être authentifié sur la page Zaim, définissez l'URL renvoyée comme URL de rappel. (À titre d'exemple, utilisons l'URL du contrôleur à créer plus tard)
python
provider.retrieveRequestToken(consumer, "URL de rappel");
Exemple
provider.retrieveRequestToken(consumer, "http://localhost:8080/authenticated");
Transit vers l'URL créée ci-dessus. Cette fois, nous allons créer un contrôleur approprié et le rediriger lors de son accès. Maintenant, lorsque vous visitez http: // localhost: 8080 /, vous serez redirigé vers la page d'authentification de Zaim.
indexController
@Controller
public class IndexController {
@Autowired
OAuthConsumer consumer;
@Autowired
OAuthProvider provider;
@RequestMapping("/")
public String index() throws Exception {
//Génération d'URL pour l'authentification
String URL = provider.retrieveRequestToken(consumer, "http://localhost:8080/authenticated");
return "redirect:" + URL;
}
}
Après avoir saisi le mot de passe de connexion dans Zaim et terminé l'authentification, l'URL de rappel définie dans "Générer l'URL de la page d'authentification Zaim" sera renvoyée. À ce stade, les deux paramètres suivants sont renvoyés ensemble, alors récupérez-les.
Utilisez ce oauth_verifier pour générer un jeton d'accès.
python
/**
*Accès avec rappel après authentification avec zaim
* @De retour de param oauthToken zaim
* @De retour de param oauthVerifier zaim
* @return
* @throws Exception
*/
@RequestMapping("/authenticated")
public String authenticated(@RequestParam(value = "oauth_token") String oauthToken,
@RequestParam(value = "oauth_verifier") String oauthVerifier, Model model)
throws Exception {
//Générer accessToken et accessTokenSecret
provider.retrieveAccessToken(consumer, oauthVerifier);
return "index";
}
Le jeton d'accès ainsi généré peut être obtenu. En sauvegardant ces deux, vous pourrez y accéder sans avoir à vous authentifier à nouveau avec zaim.
python
//Générer accessToken et accessTokenSecret
provider.retrieveAccessToken(consumer, oauthVerifier);
//Obtenez un jeton (enregistrez-le pour ne pas avoir à vous authentifier à nouveau
String accessToken = consumer.getToken();
String accessTokenSecret = consumer.getTokenSecret();
Si vous utilisez le jeton de cette manière, vous n'avez pas à vous authentifier à nouveau.
Utilisez-le comme ça
consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
provider = new CommonsHttpOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZE_URL);
//Définir le jeton enregistré
consumer.setTokenWithSecret(accessToken, accessTokenSecret);
Maintenant que j'ai le jeton d'accès, je peux enfin frapper Zaim avec l'API. Tout d'abord, préparez HttpClient.
Il y avait un bon gestionnaire d'erreurs sur la page officielle de HttpClient, je vais donc l'utiliser tel quel. Si le code de réponse lors de la frappe de l'API n'est pas de la série 200, une exception sera levée.
APIResponseHandler
/**
*Vérification du code de réponse lors de l'accès à l'API
*S'il n'y a pas de problème, renvoyez le corps
*Exception sinon normal
* https://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientWithResponseHandler.java
*/
public class APIResponseHandler implements ResponseHandler<String> {
@Override
public String handleResponse(
final HttpResponse response) throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
} else {
throw new ClientProtocolException("Unexpected response status: " + status);
}
}
}
Maintenant que nous sommes prêts, passons à l'API. Cette fois, après authentification, j'essaierai d'acquérir les informations utilisateur telles quelles.
python
/**
*Accès avec rappel après authentification avec zaim, puis obtention des informations utilisateur
* @De retour de param oauthToken zaim
* @De retour de param oauthVerifier zaim
* @return
* @throws Exception
*/
@RequestMapping("/authenticated")
public String authenticated(@RequestParam(value = "oauth_token") String oauthToken,
@RequestParam(value = "oauth_verifier") String oauthVerifier, Model model)
throws Exception {
//Générer accessToken et accessTokenSecret
provider.retrieveAccessToken(consumer, oauthVerifier);
//Préparation HttpClient
CloseableHttpClient httpclient = HttpClients.createDefault();
ResponseHandler<String> responseHandler = new APIResponseHandler();
//Signez la demande
HttpGet httpget = new HttpGet("https://api.zaim.net/v2/home/user/verify");
consumer.sign(httpget);
//Avoir
String responseBody = httpclient.execute(httpget, responseHandler);
model.addAttribute("zaimUserVerify", responseBody);
return "index";
}
Je pense que le JSON des informations de connexion a été renvoyé.
Si vous souhaitez accéder à l'API sans vous ré-authentifier après l'authentification, vous pouvez l'atteindre tel quel en définissant les accessToken et accessTokenSecret enregistrés dans consumer.
Lors de l'utilisation de accessToken et accessTokenSecret
//Définir le jeton enregistré
consumer.setTokenWithSecret(accessToken, accessTokenSecret);
//Préparation HttpClient
CloseableHttpClient httpclient = HttpClients.createDefault();
ResponseHandler<String> responseHandler = new APIResponseHandler();
//Signez la demande
HttpGet httpget = new HttpGet("https://api.zaim.net/v2/home/user/verify");
consumer.sign(httpget);
//Avoir
String responseBody = httpclient.execute(httpget, responseHandler);
model.addAttribute("zaimUserVerify", responseBody);
J'ai pu accéder à l'API de Zaim (OAuth 1.0) avec Java de cette manière.
Si vous utilisez RestTemplate de Spring, il mappera le JSON retourné à un objet et le retournera, ce qui semble être incroyablement pratique, mais je ne peux pas l'utiliser de toute façon. .. N'est-il pas possible d'utiliser un peu mieux OAuth 1.0? ..
Pour le moment, je vais mettre ce que j'ai mis en œuvre à ma manière. Je suis heureux que vous puissiez l'utiliser comme référence. https://github.com/kxn4t/saifu
Recommended Posts