Plaats een link naar de Reddit API

Beveiliging Top

Ik heb zojuist de nieuwe Learn Spring Security-cursus aangekondigd, inclusief het volledige materiaal gericht op de nieuwe OAuth2-stack in Spring Security 5:

>> BEKIJK DE CURSUS REST Top

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS

1. Overzicht

In dit tweede artikel van de serie zullen we enkele eenvoudige functionaliteit bouwen om op Reddit te posten vanuit onze applicatie, via hun API.

2. Noodzakelijke beveiliging

Laten we eerst het beveiligingsaspect uit de weg ruimen.

Om zo te Dien een link naar Reddit in, moeten we een door OAuth beveiligde bron definiëren met de reikwijdte van "indienen“:

@Bean openbaar OAuth2ProtectedResourceDetails reddit () {AuthorizationCodeResourceDetails details = nieuwe AuthorizationCodeResourceDetails (); details.setId ("reddit"); details.setClientId (clientID); details.setClientSecret (clientSecret); details.setAccessTokenUri (accessTokenUri); details.setUserAuthorizationUri (userAuthorizationUri); details.setTokenName ("oauth_token"); details.setScope (Arrays.asList ("identiteit", "submit")); details.setGrantType ("autorisatiecode"); details retourneren; }

Merk op dat we ook de reikwijdteidentiteit”Omdat we ook toegang moeten hebben tot de gebruikersaccountgegevens.

3. Is Captcha nodig?

Gebruikers die nieuw zijn bij Reddit moet een Captcha invullen om in te dienen; dat is voordat ze een bepaalde karmadrempel binnen Reddit overschrijden.

Voor deze gebruikers moeten we eerst controleren of de Captcha nodig is:

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

4. De “Post verzenden" Het formulier

Laten we vervolgens het hoofdformulier maken voor het indienen van nieuwe berichten op Reddit. Voor het indienen van een link zijn de volgende gegevens vereist:

  • titel - de titel van het artikel
  • url - de URL van het artikel
  • subreddit - de sub-reddit waarnaar de link moet worden verzonden

Laten we dus eens kijken hoe we deze eenvoudige aanmeldingspagina kunnen weergeven:

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

En natuurlijk de basis submissionForm.html:

 Post-functie submitPost () {var data = {}; $ ('form'). serializeArray (). map (functie (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];}}). Mislukken (functie (fout) {alert (error.responseText);}); } 

5. Dien een link naar Reddit in

Laten we nu eens kijken naar de laatste stap - het indienen van de daadwerkelijke link via de Reddit API.

We zullen een verzoek indienen bij Reddit met behulp van de parameters van ons submissionForm:

@Controller @RequestMapping (value = "/ api / posts") openbare klasse RedditPostRestController {@Autowired privé RedditService-service; @RequestMapping (methode = RequestMethod.POST) @ResponseBody openbare lijst indienen (@Valid @RequestBody PostDto postDto) {return service.submitPost (postDto); }}

Dit is de daadwerkelijke implementatie van de methode:

openbare lijst submitPost (PostDto postDto) {MultiValueMap param1 = constructParams (postDto); JsonNode-knooppunt = redditTemplate.submitPost (param1); retourneer parseResponse (knooppunt); } private MultiValueMap constructParams (PostDto postDto) {MultiValueMap param = nieuwe LinkedMultiValueMap (); param.add ("titel", 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 ("soort", "link"); param.add ("opnieuw indienen", "waar"); param.add ("dan", "opmerkingen"); terugkeer param; }

En de eenvoudige ontledingslogica, het afhandelen van het antwoord van de Reddit API:

privélijst parseResponse (JsonNode-knooppunt) {String resultaat = ""; JsonNode errorNode = node.get ("json"). Get ("errors"). Get (0); if (errorNode! = null) {voor (JsonNode kind: errorNode) null "," ") +"

"; return Arrays.asList (resultaat);} else {if ((node.get (" json "). get (" data ")! = null) && (node.get (" json "). get (" data ") .get (" url ")! = null)) {return Arrays.asList (" Post succesvol ingediend ", node.get (" json "). get (" data "). get (" url "). asText ());} else {return Arrays.asList ("Fout opgetreden tijdens het parseren van reactie");}}}

Dit alles werkt mee een basis-DTO:

openbare klasse PostDto {@NotNull private String-titel; @NotNull private String url; @NotNull private String-subreddit; private boolean sendReplies; privé String iden; private String captcha; }

Eindelijk, de submissionResponse.html:

Hallo

Hallo

Hier

6. Conclusie

In deze korte tutorial hebben we wat basis Dien in bij Reddit functionaliteit - simplistisch maar volledig functioneel.

In het volgende deel van deze casestudy zullen we een Plan een bericht voor later functionaliteit in onze app.

De volledige implementatie van deze tutorial is te vinden in het github-project - dit is een op Eclipse gebaseerd project, dus het zou gemakkelijk te importeren en uit te voeren moeten zijn zoals het is.

Beveiligingsbodem

Ik heb zojuist de nieuwe Learn Spring Security-cursus aangekondigd, inclusief het volledige materiaal gericht op de nieuwe OAuth2-stack in Spring Security 5:

>> BEKIJK DE CURSUS REST onder

Ik heb zojuist het nieuwe aangekondigd Leer de lente natuurlijk, gericht op de basisprincipes van Spring 5 en Spring Boot 2:

>> BEKIJK DE CURSUS