1:写在前面
服务提供者作为服务的提供方,为了安全性,接口是不可以随意调用的,为了解决这个问题,dubbo提供了token令牌机制,只需要在service配置中设置token即可,下面我们来一起看下。
2:服务提供方
2.1:服务接口
public interface MyProviderTokenService {
String sayHi(String word);
}
2.2:服务接口实现
public class MyProviderTokenServiceImpl implements MyProviderTokenService {
@Override
public String sayHi(String word) {
return "provider token: " + word;
}
}
2.3:xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
<dubbo:application name="dongshidaddy-provider" owner="dongshidaddy"/>
<dubbo:registry address="zookeeper://192.168.10.119:2181" />
<!--当前服务发布所依赖的协议;webserovice、Thrift、Hessain、http-->
<dubbo:protocol name="dubbo" port="20827"/>
<dubbo:service interface="dongshi.daddy.service.MyProviderTokenService" ref="myProviderTokenServiceImpl" token="12345678"/>
<!--Bean bean定义-->
<bean id="myProviderTokenServiceImpl" class="dongshi.daddy.service.MyProviderTokenServiceImpl"/>
</beans>
注意在<dubbo:service>
中设置了token="12345678"
,即令牌为固定值,也可以设置token="true"
,此时dubbo会通过UUID的方式随机生成一个token。
2.4:main
public class ProviderWithTokenMain {
public static void main(String[] args) throws Exception {
/*
dubbo://192.168.10.119:20827/dongshi.daddy.service.MyProviderTokenService?anyhost=true&application=dongshidaddy-provider&bean.name=dongshi.daddy.service.MyProviderTokenService&dubbo=2.0.2&generic=false&interface=dongshi.daddy.service.MyProviderTokenService&methods=sayHi&owner=dongshidaddy&pid=17848&side=provider×tamp=1638325411607&token=12345678
*/
//加载xml配置文件启动
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext("META-INF/spring/provider-with-token.xml");
context.start();
System.in.read(); // 按任意键退出
}
}
启动后生成的dubbo url如下:
dubbo://...?anyhost=true&application=dongshidaddy-provider&...&token=12345678
可以看到生成了&token=12345678
参数。
3:服务消费方
3.1:xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--当前项目在整个分布式架构里面的唯一名称,计算依赖关系的标签-->
<dubbo:application name="dongshidaddy-consumer" owner="dongshidaddy"/>
<!--点对点的方式-->
<dubbo:registry address="zookeeper://192.168.10.119:2181" />
<dubbo:reference id="myProviderTokenServiceInConsumerSide"
interface="dongshi.daddy.service.MyProviderTokenService"/>
</beans>
注意此时设置了连接注册中心。
3.2:main
public class ConsumerWithTokenMain {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext("consumer-with-token.xml");
context.start();
MyProviderTokenService myProviderTokenService = (MyProviderTokenService) context.getBean("myProviderTokenServiceInConsumerSide");
System.out.println(myProviderTokenService.sayHi("hello"));
System.in.read();
}
}
调用正常。因为这种方式是通过注册中心的,token信息会自动带到服务提供者端,所以可以正常调用,下面我们看下通过api config的方式绕过注册中心的情况。
3.3:api配置绕过注册中心
public static void main(String[] args) {
// 当前应用配置
ApplicationConfig application = new ApplicationConfig();
application.setName("dongshidaddy-consumer");
application.setOwner("dongshidaddy");
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
// registry.setAddress("zookeeper://192.168.10.119:2181");
registry.setAddress("N/A");
// 注意:ReferenceConfig为重对象,内部封装了与注册中心的连接,以及与服务提供方的连接
// 引用远程服务
ReferenceConfig<MyProviderTokenService> reference = new ReferenceConfig<MyProviderTokenService>(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
reference.setApplication(application);
reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
reference.setInterface(MyProviderTokenService.class);
reference.setUrl("dubbo://192.168.10.119:20827");
// 和本地bean一样使用xxxService
MyProviderTokenService myProviderTokenService = reference.get(); // 注意:此代理对象内部封装了所有通讯细节,对象较重,请缓存复用
String s = myProviderTokenService.sayHi("hello dubbo1");
System.out.println(s);
}
运行输出,无效的token相关错误,如下:
下面我们修改代码增加token的配置,如下:
再次调用,就正常了。