Cross-Origin Resource Sharing - স্প্রিং বুট

crosssecurityspring-boot

Cross-Origin Resource Sharing (CORS) কি?


যখন আমরা ব্রাউজারে একটা URL টাইপ করি, তখন ব্রাউজার সেই এড্রেস কে ওই সাইটের জন্য মেইন এড্রেস হিসাবে চিন্তা করে। মানে হচ্ছে আপনি যদি টাইপ করলেন www.marufh.com তাহলে ব্রাউজার marufh.com কে অরিজিনাল বা মেইন রিসোর্স সার্ভার হিসাবে চিন্তা করবে।


এবার ধরুন, www.marufh.com এ বসে গিটহাব থেকে কিছু ডাটা এনে এই সাইটে দেখতে চাই। এই যে একটা ওয়েবসাইটে বসে আমি অন্য একটা এড্রেস থেকে ডাটা আনা নেয়া করতে চাই, একেই Cross-Origin Resource Sharing বলে। মানে হচ্ছে আপনি একটা অরিজিন বা এড্রেস এ বসে অন্য একটা এড্রেস থেকে কিছু ডাটা আদান-প্রদান করতে চান।




সমস্যা কোথায়?

সমস্যা হচ্ছে সিকিউরিটির জন্য সব ওয়েব সার্ভারে বাই-ডিফল্ট CORS বন্ধ করা থাকে। কারণ, আমি চাইনা সবাই আমার সার্ভারে যখন খুশি তখন, যা খুশি তাই পাওয়ার রিকোয়েস্ট করুক। মোট কথা হচ্ছে জানা ডোমেইন ছাড়া কাউকে কোন এপিআই কল করতে দিবো না। আপনি যদি অন্য ডোমেইন থেকে আপনার সার্ভারে ডাটা আনা নেয়া করতে দিতে চান, তাহলে জেনে, শুনে এবং বুঝে সার্ভারকে অনুমতি দিতে হয়, সে যেন অন্য ডোমেইন থেকে আসা কল, স্পেশালি এজাক্স কলের প্রতি সাড়া দেয়।



কিভাবে কাজ হয়?


CORS হচ্ছে আপনার সার্ভারের সেটিং, আপনি বলে দিবেন অন্য ডোমেইন থেকে কল রিসিভ করবেন কি করবেন না। করলে কোন কোন মেথড এলাউ করবেন, কোন ধরণের ইউআরএল এর জন্য এলাউ করবেন ইত্যাদি। ক্লায়েন্ট বা ব্রাউজারকে এক্ষেত্রে শুধু মাত্র নিশ্চিত হতে হয় যে, বতর্মান ডোমেইন থেকে কল করলে সার্ভার একসেপ্ট করবে কি করবে না। ব্রাউজারের এই কাজ নিজেই করে, প্রতিটা রিকোয়েস্ট পাঠানোর আগে, ব্রাউজার কোন ডোমেইনে বসে আছে সেটা জানিয়ে অন্য সার্ভারকে একটা OPTION কল করে, OPTION থেকে যদি পসিটিভ রেসাল্ট পায়, তাহলে ফাইনাল রিকোয়েস্ট পাঠায়।



স্প্রিং বুট সার্ভারে CORS সেটাপ করা


অন্য যেকোন সার্ভারের মতো টমকেট সার্ভারও CORS বন্ধ করা থাকে। স্প্রিং বুটে একটা ফিল্টার লিখে সেটা কনফিগার করে নেয়া যায়

public class CorsConfigFilter extends CorsFilter {

    public CorsConfigFilter() {
        super(configurationSource());
    }


    private static UrlBasedCorsConfigurationSource configurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.setMaxAge(36000L);
        config.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);
        return source;
    }
}


১. config.addAllowedOrigin("*");
২. config.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"));
৩. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);
        


১. এখানে প্রথম লাইন হচ্ছে কোন কোন সার্ভার থেকে রিকোয়েস্টআসলে এলাউ করবো। * মানে সব ডোমেইন থেকে (ভালো বুদ্বি না), এখানে স্ট্রিং এরে লিখে সার্ভারের ডোমেইন না বলে দেয়া যায়


২. কোন কোন মেথড এলাউ করবো।


৩. URL বলে দেয়া যায়,কোন কোন URL বা কোন ধরণের URL রিকোয়েস্ট করলে রিস্পন্স করবে।



আরো আছে


যদি সার্ভারের সিকিউর কোন এপিআই একসেস করতে চান, তাহলে আরেকটু সেটাপ লাগবে। সেটা হচ্ছে WebSecurityConfigurerAdapter এর মধ্যে একটা বিন বানাতে হবে


@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
      ...................................

      @Bean
      CorsConfigurationSource corsConfigurationSource() {
          CorsConfiguration configuration = new CorsConfiguration();
          configuration.setAllowedOrigins(Arrays.asList("*"));
          configuration.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"));
          configuration.setAllowCredentials(true);
          configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
          source.registerCorsConfiguration("/**", configuration);
          return source;
      }
  }

হ্যাপি CORS। ধন্যবাদ