Code Monkey home page Code Monkey logo

spmia-chapter7's People

Contributors

carnellj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spmia-chapter7's Issues

JWT Example, Chapter 7, How do DefaultTokenServices defaultTokenServices work?

In file JWTOAuth2Config.java shouldn't the configure function also have endpoints.tokenServices(tokenServices) ? tokenServices is autowired in this file but never used? When I add it myself I lose the JWT token and start getting the original oauth uid token again.

`
@OverRide
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer, jwtAccessTokenConverter));

	endpoints.tokenStore(tokenStore)
		.accessTokenConverter(jwtAccessTokenConverter)
		.tokenEnhancer(tokenEnhancerChain)
		.tokenServices(tokenServices) // I added this
		.authenticationManager(authenticationManager)
		.userDetailsService(userDetailsService);
}

`

I am confused how the DefaultTokenServices work because I added defaultTokenServices.setAccessTokenValiditySeconds(7200); and its not working. So I am confused how tokenServices even work in this setup?

`
@bean
@primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();

	defaultTokenServices.setTokenStore(tokenStore());
	defaultTokenServices.setAccessTokenValiditySeconds(7200);  // I added this
	defaultTokenServices.setSupportRefreshToken(true);
	return defaultTokenServices;
}

`

OAuth2RestTemplate Config question

Hi, John. I am reading your book. But it occurred a Error while config Oauth2RestTemplate. The Following is my Bean code:

@Bean
    public OAuth2RestTemplate oAuth2RestTemplate(OAuth2ProtectedResourceDetails details, @Qualifier("oauth2ClientContext") OAuth2ClientContext context) {
        return new OAuth2RestTemplate(details, context);
    }

The Following is consle stack trace info:

Description:

Parameter 0 of method oAuth2RestTemplate in com.isaac.licenses.LicenseApplication required a bean of type 'org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails' that could not be found.

The following candidates were found but could not be injected:
	- Bean method 'oauth2RemoteResource' in 'OAuth2RestOperationsConfiguration.SingletonScopedConfiguration' not loaded because AnyNestedCondition 0 matched 2 did not; NestedCondition on OAuth2RestOperationsConfiguration.ClientCredentialsCondition.NoWebApplication @ConditionalOnWebApplication found 'session' scope and did not find reactive web application classes; NestedCondition on OAuth2RestOperationsConfiguration.ClientCredentialsCondition.ClientCredentialsConfigured @ConditionalOnProperty (security.oauth2.client.grant-type=client_credentials) did not find property 'grant-type'


Action:

Consider revisiting the entries above or defining a bean of type 'org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails' in your configuration.

I am using SpringBoot 2.2.4.RELEASE and SpringCloud Hoxton.SR1 and spring-cloud-starter-oauth2

The import org.apache.http.HttpHost cannot be resolved

Hi,

I pulled the project down and imported it into STS. I noticed there are some problems in STS with resolving classes related to httpclient dependency. Are you getting these as well?

Update : Originally this seemed to be an STS issue, as I could build it from command line with Maven. However, I still can not run it outside with Maven and the boot plugin.

Update 2 : I was able to get it to compile by adding the httpcore:4.4.1 dependency to the pom.xml.

Regards,

Jeff

Cannot convert access token to JSON.

I was using a modified version of your authentication-service, and organization service on the branch JWT_EXAMPLE. What I've changed was the signing-key only, Whenever I request an access token on the Authorization server. I receive this response.

{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdhbml6YXRpb25JZCI6InNjb3JwaW9uIiwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJ3ZWJjbGllbnQiXSwiZXhwIjoxNDkxNzg1MTE2LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6ImExOWZjZmY2LWE2MzctNDExZi04MGYzLWUyOTZhNzJlYWZmYSIsImNsaWVudF9pZCI6Im15YXBwY2xpZW50In0.FjqKMt6rtZnfydEkt4FL7ljcCu4zefj2Z6SUhM0-E6g", "token_type": "bearer", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdhbml6YXRpb25JZCI6InNjb3JwaW9uIiwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJ3ZWJjbGllbnQiXSwiYXRpIjoiYTE5ZmNmZjYtYTYzNy00MTFmLTgwZjMtZTI5NmE3MmVhZmZhIiwiZXhwIjoxNDk0MzMzOTE2LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6IjMwZTFkYTc4LWIwNjYtNDhhZi1hMDFhLTMxNDQ5MTY4OTkzZSIsImNsaWVudF9pZCI6Im15YXBwY2xpZW50In0.IoFk3pGe8MvsREBt2yrzJkQYyEbzxNztHYyleExjofM", "expires_in": 43199, "scope": "webclient", "organizationId": "scorpion", "jti": "a19fcff6-a637-411f-80f3-e296a72eaffa" }

What i then do is access the organization resource as follows.
curl -i -H "Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmdhbml6YXRpb25JZCI6InNjb3JwaW9uIiwidXNlcl9uYW1lIjoiYWRtaW4iLCJzY29wZSI6WyJ3ZWJjbGllbnQiXSwiZXhwIjoxNDkxNzg1MTE2LCJhdXRob3JpdGllcyI6WyJST0xFX0FETUlOIl0sImp0aSI6ImExOWZjZmY2LWE2MzctNDExZi04MGYzLWUyOTZhNzJlYWZmYSIsImNsaWVudF9pZCI6Im15YXBwY2xpZW50In0.FjqKMt6rtZnfydEkt4FL7ljcCu4zefj2Z6SUhM0-E6g" -X GET http://localhost:8085/api/organization

It then gives me this response.

{ "error": "invalid_token", "error_description": "Cannot convert access token to JSON" }

Is there any configuration that's needed?

Null Pointer Exception when calling GET request /auth/user

Spring Microservices In Action 7.2 ends

@RequestMapping(value = { "/user" }, produces = "application/json")
	public Map<String, Object> user(OAuth2Authentication user) {
		Map<String, Object> userInfo = new HashMap<>();
		userInfo.put("user", user.getUserAuthentication().getPrincipal());
		userInfo.put("authorities", AuthorityUtils.authorityListToSet(user.getUserAuthentication().getAuthorities()));
		return userInfo;
	}

OAuth2Authentication user is null

Can't propagate OAuth2 access token

Hi John,

I'm right now trying to finish chapter 7 (Propagating the OAuth2 access token), but I'm getting this error from the console when I'm trying to call 2 services built like the organization-service:

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

...

hystrix.DelegatingUserContextCallable.call(DelegatingUserContextCallable.java:22) ~[classes/:na]

from postman I got this message error:

{
"timestamp": 1492724749244,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.beans.factory.BeanCreationException",
"message": "Error creating bean with name 'scopedTarget.oauth2ClientContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.",
"path": "/v1//"
}

licensing service can't run

i read your book and see your demo.but the licensing service can't run, it looks like bean can't be found. how to resolve ?
---------------------------------------------------------------------------------------------------------i am line
Error starting ApplicationContext. To display the auto-configuration report enable debug logging (start with --debug)

Error starting ApplicationContext. To display the auto-configuration report enable debug logging (start with --debug)

2017-07-12 11:32:15.681 ERROR 16900 --- [ main] o.s.boot.SpringApplication : Application startup failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'organizationRestTemplateClient': Unsatisfied dependency expressed through field 'restTemplate': Error creating bean with name 'oauth2RestTemplate' defined in com.thoughtmechanix.licenses.Application: Unsatisfied dependency expressed through method 'oauth2RestTemplate' parameter 0: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'oauth2RestTemplate' defined in com.thoughtmechanix.licenses.Application: Unsatisfied dependency expressed through method 'oauth2RestTemplate' parameter 0: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) ~[spring-context-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at com.thoughtmechanix.licenses.Application.main(Application.java:59) [classes/:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'oauth2RestTemplate' defined in com.thoughtmechanix.licenses.Application: Unsatisfied dependency expressed through method 'oauth2RestTemplate' parameter 0: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1214) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
... 19 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails] found for dependency [org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1406) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1057) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
... 33 common frames omitted

Having Bad Credentials on /oauth2/token even with correct credentials passed.

I'm trying out spring securty oauth2 with in memory users, and running it through postman.

I've only set 3 classes namely,

Application.java


@SpringBootApplication
@RestController
@EnableResourceServer
@EnableAuthorizationServer
public class Application {

    @RequestMapping(value = { "/user" }, produces = "application/json")
    public Map<String, Object> user(OAuth2Authentication user) {
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("user", user.getUserAuthentication().getPrincipal());
        userInfo.put("authorities", AuthorityUtils.authorityListToSet(user.getUserAuthentication().getAuthorities()));
        return userInfo;
    }



    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }


}

WebSecurityConfigure.java

@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests()
               .anyRequest().authenticated() .antMatchers("/oauth/token/").permitAll().and().formLogin().and().httpBasic();
    }

    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser("john.carnell").password("password1").roles("USER")
                .and()
                .withUser("william.woodward").password("password2").roles("USER", "ADMIN");
    }
}

and lastly

@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("eagleeye")
                .secret("thisissecret")
                .authorizedGrantTypes("refresh_token", "password", "client_credentials")
                .scopes("webclient", "mobileclient");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }
}

However upon passing the valid credentials on POSTMAN. give me a response of

{
"timestamp": 1491436869552,
"status": 401,
"error": "Unauthorized",
"message": "Bad credentials",
"path": "/oauth/token/"
}

Did I missed anything on my configuration?

I was basing this on your example I just removed Hystrix, Zuul.. This is just a standalone Auth server. Here are the parameters I have passed on Postman (Check the images below)

http://imgur.com/U21U8jo

http://imgur.com/j7Qb6eA

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.