פרסם קישור ל- API של Reddit

למעלה אבטחה

הרגע הכרזתי על הקורס החדש ללמוד Spring Spring Security, כולל החומר המלא שהתמקד בערמת OAuth2 החדשה ב- Spring Security 5:

>> בדוק את הקורס REST למעלה

רק הכרזתי על החדש למד אביב קורס, המתמקד ביסודות האביב 5 ומגף האביב 2:

>> בדוק את הקורס

1. סקירה כללית

במאמר השני הזה של הסדרה נבנה פונקציונליות פשוטה לפרסום ב- Reddit מהיישום שלנו, דרך ה- API שלהם.

2. אבטחה הכרחית

ראשית - בואו נפנה את הפן הביטחוני.

כדי הגש קישור ל- Reddit, עלינו להגדיר משאב מוגן באמצעות OAuth תְחוּם של “שלח“:

@Bean OAuth2ProtectedResourceDetails ציבורי reddit () {AuthorizationCodeResourceDetails פרטים = חדש AuthorizationCodeResourceDetails (); details.setId ("reddit"); details.setClientId (clientID); details.setClientSecret (clientSecret); details.setAccessTokenUri (accessTokenUri); details.setUserAuthorizationUri (userAuthorizationUri); details.setTokenName ("oauth_token"); details.setScope (Arrays.asList ("זהות", "הגש")); details.setGrantType ("קוד הרשאה"); פרטי החזרה; }

שים לב שאנחנו גם מציינים את תְחוּםזהותכי אנו זקוקים גם לגישה למידע על חשבון המשתמש.

3. האם יש צורך בקפטצ'ה?

משתמשים חדשים ב- Reddit צריך למלא קפטצ'ה על מנת להגיש; זה לפני שהם עוברים רף מסוים של קארמה בתוך Reddit.

עבור משתמשים אלה, ראשית עלינו לבדוק אם יש צורך ב- Captcha:

מחרוזת פרטית needsCaptcha () {מחרוזת תוצאה = redditRestTemplate.getForObject ("//oauth.reddit.com/api/needs_captcha.json", String.class); תוצאת החזרה; } מחרוזת פרטית getNewCaptcha () {כותרות HttpHeaders = HttpHeaders חדשות (); headers.setContentType (MediaType.APPLICATION_JSON); HttpEntity req = HttpEntity חדש (כותרות); Map param = HashMap חדש (); param.put ("api_type", "json"); תוצאת ResponseEntity = redditRestTemplate.postForEntity ("//oauth.reddit.com/api/new_captcha", req, String.class, param); מחרוזת [] split = result.getBody (). Split ("" "); split split [split.length - 2];}

4. "הגש הודעה" טופס

לאחר מכן, בואו ניצור את הטופס הראשי להגשת פוסטים חדשים ל- Reddit. הגשת קישור דורשת את הפרטים הבאים:

  • כותרת - כותרת המאמר
  • url - כתובת האתר של המאמר
  • subreddit - תת-reddit להגיש את הקישור

בואו נראה כיצד נוכל להציג את דף ההגשה הפשוט הזה:

@RequestMapping ("/ post") מחרוזת ציבורית showSubmissionForm (מודל מודל) זורק את JsonProcessingException, IOException {String needsCaptchaResult = needsCaptcha (); if (needsCaptchaResult.equalsIgnoreCase ("true")) {String iden = getNewCaptcha (); model.addAttribute ("iden", iden); } להחזיר "submissionForm"; }

וכמובן הבסיסי submissionForm.html:

 פונקציית פוסט submitPost () {var data = {}; $ ('טופס'). serializeArray (). מפה (פונקציה (x) {נתונים [x.name] = x.value;}); $ .ajax ({url: "api / posts", נתונים: JSON.stringify (data), סוג: 'POST', contentType: 'application / json'}). נעשה (פונקציה (data) {if (data.length <2) {alert (data [0]);} אחר {window.location.href = "submissionResponse? Msg =" + data [0] + "& url =" + data [1];}}). Fail (פונקציה (שגיאה) {התראה (error.responseText);}); } 

5. הגישו קישור ל- Reddit

עכשיו - בואו נסתכל על השלב האחרון - הגשת הקישור בפועל דרך ה- Reddit API.

אנו נפרסם בקשה להגיש ל- Reddit באמצעות הפרמטרים שלנו טופס הגשה:

@Controller @RequestMapping (value = "/ api / posts") מחלקה ציבורית RedditPostRestController {@ שירות RedditService פרטי פרטי; @RequestMapping (method = RequestMethod.POST) @ResponseBody רשימת משתמשים ציבורית (@Valid @RequestBody PostDto postDto) {service.submitPost return (postDto); }}

הנה יישום השיטה בפועל:

רשימה ציבורית submitPost (PostDto postDto) {MultiValueMap param1 = constructParams (postDto); צומת JsonNode = redditTemplate.submitPost (param1); החזר parseResponse (צומת); } פרטי MultiValueMap buildParams (PostDto postDto) {MultiValueMap param = חדש LinkedMultiValueMap (); param.add ("כותרת", postDto.getTitle ()); param.add ("sr", postDto.getSubreddit ()); param.add ("url", postDto.getUrl ()); param.add ("iden", postDto.getIden ()); param.add ("captcha", postDto.getCaptcha ()); אם (postDto.isSendReplies ()) {param.add ("sendReplies", "true"); } param.add ("api_type", "json"); param.add ("סוג", "קישור"); param.add ("שלח מחדש", "נכון"); param.add ("ואז", "הערות"); להחזיר פרמטר; }

והגיון הניתוח הפשוט, טיפול בתגובה מממשק ה- API של Reddit:

רשימה פרטית parseResponse (צומת JsonNode) {מחרוזת תוצאה = ""; JsonNode errorNode = node.get ("json"). Get ("שגיאות"). Get (0); אם (errorNode! = null) {עבור (ילד JsonNode: errorNode) null "," ") +"

"; להחזיר Arrays.asList (תוצאה);} אחר {if ((node.get (" json "). get (" data ")! = null) && (node.get (" json "). get (" data ") .get (" url ")! = null)) {Return Arrays.asList (" ההודעה הוגשה בהצלחה ", node.get (" json "). get (" data "). get (" url "). asText ());} אחרת {return Arrays.asList ("שגיאה התרחשה במהלך ניתוח התגובה");}}}

כל זה עובד עם DTO בסיסי:

מחלקה ציבורית PostDto {@NotNull כותרת מחרוזת פרטית; כתובת אתר מחרוזת פרטית @NotNull; מחרוזת פרטית @NotNull subreddit; sendRepies בוליאני פרטי; פרטי מחרוזת מזהה; פרטי מחרוזת מחרוזת; }

סוף - סוף, ה submissionResponse.html:

שלום

שלום

פה

6. מסקנה

במדריך מהיר זה יישמנו כמה בסיסי הגש ל- Reddit פונקציונליות - פשטנית אך פונקציונאלית לחלוטין.

בחלק הבא של מחקר מקרה זה, נבצע יישום תזמן פרסום למועד מאוחר יותר פונקציונליות באפליקציה שלנו.

ה יישום מלא של מדריך זה ניתן למצוא בפרויקט github - זהו פרויקט מבוסס ליקוי חמה, כך שיהיה קל לייבא ולהפעיל אותו כפי שהוא.

תחתית אבטחה

הרגע הכרזתי על הקורס החדש ללמוד Spring Spring Security, כולל החומר המלא שהתמקד בערמת OAuth2 החדשה ב- Spring Security 5:

>> בדוק את הקורס REST תחתון

רק הכרזתי על החדש למד אביב קורס, המתמקד ביסודות האביב 5 ומגף האביב 2:

>> בדוק את הקורס