Publier un lien vers l'API Reddit

Haut de sécurité

Je viens d'annoncer le nouveau cours Learn Spring Security, y compris le matériel complet axé sur la nouvelle pile OAuth2 dans Spring Security 5:

>> DÉCOUVREZ LE COURS REPOS Haut

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS

1. Vue d'ensemble

Dans ce deuxième article de la série, nous allons créer des fonctionnalités simples à publier sur Reddit à partir de notre application, via leur API.

2. Sécurité nécessaire

Tout d'abord, éliminons l'aspect sécurité.

Pour soumettre un lien vers Reddit , nous devons définir une ressource protégée OAuth avec la portée de « soumettre »:

@Bean public OAuth2ProtectedResourceDetails reddit() { AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails(); details.setId("reddit"); details.setClientId(clientID); details.setClientSecret(clientSecret); details.setAccessTokenUri(accessTokenUri); details.setUserAuthorizationUri(userAuthorizationUri); details.setTokenName("oauth_token"); details.setScope(Arrays.asList("identity", "submit")); details.setGrantType("authorization_code"); return details; }

Notez que nous spécifions également la portée « identité », car nous devons également accéder aux informations du compte utilisateur.

3. Le captcha est-il nécessaire?

Les utilisateurs qui sont nouveaux sur Reddit doivent remplir un Captcha pour soumettre; c'est avant qu'ils ne passent un certain seuil de karma dans Reddit.

Pour ces utilisateurs, nous devons d'abord vérifier si le Captcha est nécessaire:

private String needsCaptcha() { String result = redditRestTemplate.getForObject( "//oauth.reddit.com/api/needs_captcha.json", String.class); return result; } private String getNewCaptcha() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity req = new HttpEntity(headers); Map param = new HashMap(); param.put("api_type", "json"); ResponseEntity result = redditRestTemplate.postForEntity( "//oauth.reddit.com/api/new_captcha", req, String.class, param); String[] split = result.getBody().split("""); return split[split.length - 2]; }

4. Le formulaire « Soumettre le message »

Ensuite, créons le formulaire principal pour soumettre de nouveaux articles à Reddit. La soumission d'un lien nécessite les détails suivants:

  • title - le titre de l'article
  • url - l'URL de l'article
  • subreddit - le sous-reddit auquel soumettre le lien

Voyons donc comment nous pouvons afficher cette simple page de soumission:

@RequestMapping("/post") public String showSubmissionForm(Model model) throws JsonProcessingException, IOException { String needsCaptchaResult = needsCaptcha(); if (needsCaptchaResult.equalsIgnoreCase("true")) { String iden = getNewCaptcha(); model.addAttribute("iden", iden); } return "submissionForm"; }

Et bien sûr, le submitForm.html de base :

 Post   function submitPost(){ var data = {}; $('form').serializeArray().map(function(x){data[x.name] = x.value;}); $.ajax({ url: "api/posts", data: JSON.stringify(data), type: 'POST', contentType:'application/json' }).done(function(data) { if(data.length < 2){ alert(data[0]);} else{ window.location.href="submissionResponse?msg="+ data[0]+"&url="+data[1]; } }).fail(function(error) { alert(error.responseText); }); } 

5. Soumettez un lien vers Reddit

Maintenant - jetons un coup d'œil à la dernière étape - soumettre le lien réel via l'API Reddit.

Nous POSTERONS une demande de soumission à Reddit en utilisant les paramètres de notre formulaire de soumission :

@Controller @RequestMapping(value = "/api/posts") public class RedditPostRestController { @Autowired private RedditService service; @RequestMapping(method = RequestMethod.POST) @ResponseBody public List submit(@Valid @RequestBody PostDto postDto) { return service.submitPost(postDto); } }

Voici l'implémentation réelle de la méthode:

public List submitPost(PostDto postDto) { MultiValueMap param1 = constructParams(postDto); JsonNode node = redditTemplate.submitPost(param1); return parseResponse(node); } private MultiValueMap constructParams(PostDto postDto) { MultiValueMap param = new LinkedMultiValueMap(); param.add("title", postDto.getTitle()); param.add("sr", postDto.getSubreddit()); param.add("url", postDto.getUrl()); param.add("iden", postDto.getIden()); param.add("captcha", postDto.getCaptcha()); if (postDto.isSendReplies()) { param.add("sendReplies", "true"); } param.add("api_type", "json"); param.add("kind", "link"); param.add("resubmit", "true"); param.add("then", "comments"); return param; }

Et la logique d'analyse simple, gérant la réponse de l'API Reddit:

private List parseResponse(JsonNode node) { String result = ""; JsonNode errorNode = node.get("json").get("errors").get(0); if (errorNode != null) { for (JsonNode child : errorNode) null", "") + "

"; return Arrays.asList(result); } else { if ((node.get("json").get("data") != null) && (node.get("json").get("data").get("url") != null)) { return Arrays.asList("Post submitted successfully", node.get("json").get("data").get("url").asText()); } else { return Arrays.asList("Error Occurred while parsing Response"); } } }

Tout cela fonctionne avec un DTO de base :

public class PostDto { @NotNull private String title; @NotNull private String url; @NotNull private String subreddit; private boolean sendReplies; private String iden; private String captcha; }

Enfin - le submitResponse.html :

Hello

Hello

Here

6. Conclusion

Dans ce tutoriel rapide, nous avons implémenté des fonctionnalités de base de Submit to Reddit - simplistes mais entièrement fonctionnelles.

Dans la partie suivante de cette étude de cas, nous allons implémenter une fonctionnalité de publication de calendrier pour plus tard dans notre application.

L' implémentation complète de ce didacticiel se trouve dans le projet github - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.

Fond de sécurité

Je viens d'annoncer le nouveau cours Learn Spring Security, y compris le matériel complet axé sur la nouvelle pile OAuth2 dans Spring Security 5:

>> VOIR LE COURS REPOS bas

Je viens d'annoncer le nouveau cours Learn Spring , axé sur les principes de base de Spring 5 et Spring Boot 2:

>> VOIR LE COURS